• React Native FlatList


    FlatList是我们项目中经常使用的一个组件,

    下面简述下使用中要注意的问题

    一、keyExtractor

    keyExtractor的唯一性

    /**
         * Used to extract a unique key for a given item at the specified index. Key is used for caching
         * and as the react key to track item re-ordering. The default extractor checks `item.key`, then
         * falls back to using the index, like React does.
         */
        keyExtractor?: (item: ItemT, index: number) => string;

    /**
    *用于在指定索引处提取给定项的唯一键。密钥用于缓存
    *并作为跟踪项目重新订购的反应键。默认提取器检查'item.key',然后
    *退回到使用索引,就像React一样。
    */

    keyExtractor决定了子组件是否需要新建。只要有新的keyExtractor,那么就会构造新的子组件。

    所以我们需要确保keyExtractor的唯一性,如果keyExtractor不唯一,就会出现莫名其妙的错误

    一般我们有以下两种方式设置keyExtractor

    1、依赖当前数据模型的唯一标记userId(此方案需要后台返回的数据ID是唯一的)

    keyExtractor={(item)=>item.userId}

    2、前端自己生成

    let extraUniqueKey = () => Math.random().toString();

    二、renderItem、ListHeaderComponent

    renderItem、ListHeaderComponent组件封装成函数时,注意this的绑定,

    如果不想考虑this的问题,建议直接使用箭头函数

    详情参考:React Native bind函数 bind(this)

    先看效果:

    代码如下:

    1、使用箭头函数(推荐)

        private showFlatList() {
            let dataList = this.props.listData
            if (dataList && dataList.length) {
                let extraUniqueKey = () => Math.random().toString();
                return (
    
                    <FlatList
                        style={{
                            backgroundColor: '#ffffff',
                            height: (44 * (dataList.length > 5 ? 4 : dataList.length) + 44),
                            marginHorizontal: 15,
                            marginTop: 20,
                        }}
                        data={dataList}
                        renderItem={this.renderUserItem}
                        // keyExtractor={(item)=>item.userId}
                        keyExtractor={extraUniqueKey}
                        ListHeaderComponent={this.listHeaderView}
                        showsVerticalScrollIndicator={false}
                    />
                );
            }
        }
    
        // 表头(箭头函数)
        listHeaderView = () => {
            return (
                <View style={{
                    backgroundColor: '#E7F1FF',
                    height: 44,
                    flexDirection: 'row',
                    justifyContent: 'space-around',
                    alignItems: 'center',
                }}>
    
                    <Text style={style.itemText}>{this.showStr()}</Text>
                    <Text style={style.itemText}>来来来 </Text>
    
                </View>)
        }
    
        // 表格 (箭头函数)
        renderUserItem = (renderItem: ListRenderItemInfo<NotEvaUserModel>) => {
            let item: NotEvaUserModel = renderItem.item
            return (
                <View style={style.itemBg}>
                    <Text style={style.itemText}>{this.showStr()}</Text>
                    <Text style={style.itemText}>{item.userName}</Text>
                </View>
            )
        }
    
        showStr() {
            return '我是showStr函数'
        }

    2、使用普通函数,且renderItem、ListHeaderComponent中使用到this(建议直接bind(this)

    实际验证renderUserItem必须绑定this,listHeaderView不绑定this也可以(纯属走运,不推荐)

    原因如下

    这是因为都属于调用后执行且renderUserItem是有参函数,listHeaderView是无参函数且只会触发一次

    详情参考:React Native 函数的调用

    private showFlatList() {
            let dataList = this.props.listData
            if (dataList && dataList.length) {
                let extraUniqueKey = () => Math.random().toString();
                return (
    
                    <FlatList
                        style={{
                            backgroundColor: '#ffffff',
                            height: (44 * (dataList.length > 5 ? 4 : dataList.length) + 44),
                            marginHorizontal: 15,
                            marginTop: 20,
                        }}
                        data={dataList}
                        renderItem={this.renderUserItem.bind(this)}
                        // keyExtractor={(item)=>item.userId}
                        keyExtractor={extraUniqueKey}
                        ListHeaderComponent={this.listHeaderView.bind(this)}
                        showsVerticalScrollIndicator={false}
                    />
                );
            }
        }
    
        // 表头(普通函数)
        listHeaderView () {
            return (
                <View style={{
                    backgroundColor: '#E7F1FF',
                    height: 44,
                    flexDirection: 'row',
                    justifyContent: 'space-around',
                    alignItems: 'center',
                }}>
    
                    <Text style={style.itemText}>{this.showStr()}</Text>
                    <Text style={style.itemText}>来来来 </Text>
    
                </View>)
        }
    
        // 表格 (普通函数)
        renderUserItem (renderItem: ListRenderItemInfo<NotEvaUserModel>) {
            let item: NotEvaUserModel = renderItem.item
            return (
                <View style={style.itemBg}>
                    <Text style={style.itemText}>{this.showStr()}</Text>
                    <Text style={style.itemText}>{item.userName}</Text>
                </View>
            )
        }
    
        showStr() {
            return '我是showStr函数'
        }

    3、使用普通函数,且renderItem、ListHeaderComponent中未使用到this(不推荐

    不用考虑this绑定的情况

    private showFlatList() {
            let dataList = this.props.listData
            if (dataList && dataList.length) {
                let extraUniqueKey = () => Math.random().toString();
                return (
    
                    <FlatList
                        style={{
                            backgroundColor: '#ffffff',
                            height: (44 * (dataList.length > 5 ? 4 : dataList.length) + 44),
                            marginHorizontal: 15,
                            marginTop: 20,
                        }}
                        data={dataList}
                        renderItem={this.renderUserItem}
                        // keyExtractor={(item)=>item.userId}
                        keyExtractor={extraUniqueKey}
                        ListHeaderComponent={this.listHeaderView}
                        showsVerticalScrollIndicator={false}
                    />
                );
            }
        }
    
        // 表头(普通函数)
        listHeaderView () {
            return (
                <View style={{
                    backgroundColor: '#E7F1FF',
                    height: 44,
                    flexDirection: 'row',
                    justifyContent: 'space-around',
                    alignItems: 'center',
                }}>
    
                    <Text style={style.itemText}>我是showStr函数</Text>
                    <Text style={style.itemText}>来来来 </Text>
    
                </View>)
        }
    
        // 表格 (普通函数)
        renderUserItem (renderItem: ListRenderItemInfo<NotEvaUserModel>) {
            let item: NotEvaUserModel = renderItem.item
            return (
                <View style={style.itemBg}>
                    <Text style={style.itemText}>我是showStr函数</Text>
                    <Text style={style.itemText}>{item.userName}</Text>
                </View>
            )
        }
    
    }
    
    const style = StyleSheet.create({
    
        bg: {
            backgroundColor: '#FFFFFF',
            borderRadius: 10,
             DeviceHelp.screenW - 100,
        },
    
        toptext: {
            fontWeight: 'bold',
            color: '#333333',
            marginTop: 20,
            textAlign: 'center',
            fontSize: DeviceHelp.fontSize(17)
        },
    
        centerText: {
            color: '#505A82',
            paddingTop: 15,
            paddingLeft: 15,
            paddingRight: 15,
            fontSize: DeviceHelp.fontSize(15)
        },
    
        itemBg: {
            height: 44,
            flexDirection: 'row',
            justifyContent: 'space-around',
            alignItems: 'center',
            backgroundColor: "#EFEFEF",
        },
    
        itemText: {
            color: '#333333',
            fontSize: DeviceHelp.fontSize(15),
        },
    
        line: {
            marginTop: 20,
            backgroundColor: '#99999955',
            height: 1,
        },
    
        btnText: {
            marginTop: 15,
            marginBottom: 15,
            color: "#3498FE",
            fontWeight: "bold",
            textAlign: "center",
            fontSize: DeviceHelp.fontSize(18),
        },
    
    
    })

     综上:

    推荐方案1和2

    箭头函数直接使用,普通函数bind(this)

  • 相关阅读:
    python打包成exe可执行文件(pyinstaller)
    pandas入门:pandas的数据结构介绍
    NumPy基础:范例-随机漫步
    NumPy基础:随机数生成
    NumPy基础:线性代数
    NOIP2018总结
    luogu P2327 [SCOI2005]扫雷
    luogu P3197 [HNOI2008]越狱
    luogu P1578 奶牛浴场
    luogu P1003 铺地毯
  • 原文地址:https://www.cnblogs.com/lijianyi/p/15578724.html
Copyright © 2020-2023  润新知