《ReactNative系列講義》進階篇---04.FlatList(一)

| 版權聲明:本文爲博主原創文章,未經博主允許不得轉載。

一、簡介

FlatList,平面列表。應用場景一
般是有大量的數據一條一條的羅列出來。這些數據的屬性相同,但是內容不一樣。那現實中究竟是怎樣的一種情景呢,下面我們一起來看看FlatList的基本用法。

二、基礎知識

1. FlatList有哪些特性?
  • 支持跨平臺(同時支持Android和IOS等平臺)
  • 支持水平佈局
  • 行組件顯示或隱藏時可配置回調事件
  • 支持單獨的頭部文件
  • 支持單獨的尾部文件
  • 支持自定義行間分割線
  • 支持下拉刷新
  • 支持上拉加載
  • 支持跳轉到指定行(ScrollToIndex)
2. 支持兩種用法?
  • 簡單用法:繼承Component類
  • 複雜用法:繼承PureComponent類

三、應用

1. 簡單用法
  • 按照常規調用組件的方式調用
import React, { Component } from 'react';
import { FlatList } from 'react-native';

export default class SampleFlatList extends Component {
    render() {
        return(
            <FlatList
                // 頁面需要渲染的數據,數組類型
                data={[{name: 'a'}, {name: 'b'}]}
                // 每條數據展示的UI佈局
                renderItem={({item}) => <Text>{item.key}</Text>}
                // 橫向滾動
                horizontal={true}
            />
        );
    }
}
2. 複雜用法
  • 類繼承PureComponent,進一步優化性能和減少bug產生的可能
import React, { PureComponent } from 'react';
import { FlatList, TouchableOpacity, Text, View } from 'react-native';
export default class FlatListBasic extends PureComponent{
    // 數據容器,用來存儲數據
    dataContainer = [];

    constructor(props) {
        super(props);

        this.state = {
            // 存儲數據的狀態
            sourceData : []
            ,selected: (new Map(): Map<String, boolean>)
        }
    }

    // 當視圖全部渲染完畢之後執行該生命週期方法
    componentDidMount() {
        // 創造模擬數據
        for (let i = 0; i < 10; i ++) {
            let obj = {
                id: i
                ,title: i + '只柯基'
            };

            //  將模擬數據存入數據容器中
            this.dataContainer.push(obj);
        }

        // 將存儲的數據賦予狀態並更新頁面
        this.setState({
            sourceData: this.dataContainer
        });
    }

    /**
     * 此函數用於爲給定的item生成一個不重複的Key。
     * Key的作用是使React能夠區分同類元素的不同個體,以便在刷新時能夠確定其變化的位置,減少重新渲染的開銷。
     * 若不指定此函數,則默認抽取item.key作爲key值。若item.key也不存在,則使用數組下標
     *
     * @param item
     * @param index
     * @private
     */
    // 這裏指定使用數組下標作爲唯一索引
    _keyExtractor = (item, index) => index;

    /**
     * 使用箭頭函數防止不必要的re-render;
     * 如果使用bind方式來綁定onPressItem,每次都會生成一個新的函數,導致props在===比較時返回false,
     * 從而觸發自身的一次不必要的重新render,也就是FlatListItem組件每次都會重新渲染。
     * 
     * @param id
     * @private
     */
    _onPressItem = (id: string) => {
        this.setState((state) => {
            const selected = new Map(state.selected);
            selected.set(id, !selected.get(id));
            return {selected}
        });
    };

    // 加載item佈局
    _renderItem = ({item}) =>{
        return(
            <FlatListItem
                id={item.id}
                onPressItem={ this._onPressItem }
                selected={ !!this.state.selected.get(item.id) }
                title={ item.title }
            />
        );
    };

    // 空佈局
    _renderEmptyView = () => (
        <View><Text>EmptyView</Text></View>
    );

    render() {
        return(
            <FlatList
                data={ this.state.sourceData }
                // 實現PureComponent時使用
                extraData={ this.state.selected }
                keyExtractor={ this._keyExtractor }
                renderItem={ this._renderItem }
                ItemSeparatorComponent={({highlighted}) => (<View style={{ height:1, backgroundColor:'#000' }}></View>)}
                ListEmptyComponent={ this._renderEmptyView }
            />
        );
    }
}

// 封裝Item組件
class FlatListItem extends React.PureComponent {
    _onPress = () => {
        this.props.onPressItem(this.props.id);
    };

    render() {
        return(
            <TouchableOpacity
                {...this.props}
                onPress={this._onPress}
                style={{ height: 40, justifyContent: 'center', alignItems: 'center' }}
            >
                <Text>{this.props.title}</Text>
            </TouchableOpacity>
        );
    }
}

四、總結

本篇文章實現了FlatList的基本功能—數據展示,下篇文章我們一起來學習一下如何添加上拉加載更多和下拉刷新功能。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章