代码之家  ›  专栏  ›  技术社区  ›  jdoej

React Native-将keyExtractor与FlatList一起使用

  •  48
  • jdoej  · 技术社区  · 8 年前

    我得到了:

    "VirtualizedList: missing keys for items, make sure to specify a key property on an item or provide a custom keyExtractor"
    

    很困惑。。。,我传递给它的数组在数组中的每个对象中都定义了一个键属性。我在这里定义了这个数组。状态我在控制台中快速打印出来,以确保: print out of array

    数组中的每个对象定义为:

      var obj = {key: doc.id, value: doc.data()};
    

    (文档和数据来自我应用程序的另一部分,但我知道doc.id是唯一的)

    在谷歌搜索之后,我尝试定义一个密钥提取程序,如下所示:

    _keyExtractor = (item, index) => item.key;
    

    下面是我的平面列表定义:

      <FlatList
            style={{}}
            data={this.state.FeedDataCollection}
            keyExtractor={this._keyExtractor}
            renderItem={(rowData) =>this.RenderFeedCard(rowData)}
          />
    

    仍然收到相同的错误,此时还不确定如何处理或它做错了什么。有什么想法吗?非常感谢!

    10 回复  |  直到 8 年前
        1
  •  58
  •   Sarantis Tofas    8 年前

    “VirtualizedList:缺少项的键,请确保指定键 属性或提供自定义keyExtractor“

    这是一个警告,提示列表中的元素缺少键。这些独特的键允许VirtualizedList(FlatList的构建基础)跟踪项目,并且在效率方面非常重要。

    您必须选择一个独特的关键道具,如 id 或 email .

    这个 keyExtractor 退回到使用 index 默认情况下。但警告仍将可见。

    例子: 对象定义为 {key: doc.id, value: doc.data()} 可在提取器中用作:

    keyExtractor={(item, index) => item.key}
    

    平面列表组件应如下所示:

    <FlatList
      style={{}}
      data={this.state.FeedDataCollection}
      keyExtractor={(item, index) => item.key}
      renderItem={(rowData) =>this.RenderFeedCard(rowData)}
    />
    
        2
  •  37
  •   amirhosein    7 年前

    我这样做并为我工作:

    keyExtractor={(item, index) => 'key'+index}
    
        3
  •  3
  •   halfer Jatin Pandey    4 年前

    此错误的重要性在于您开始更改或删除数组中的任何对象时,因为如果您不提供该键,列表将如何更新。

    React Native处理无键列表更改的方法是删除屏幕上可见的所有内容,然后查看新的数据数组并为每个元素呈现单个元素。

    我们不希望仅仅因为对数据数组做了一个小小的更改,就让React Native重建整个列表。理想情况下,我们希望React Native专门检测我们删除或更改的对象,并进行相应的更新,但如果我们不提供密钥,则不会发生这种情况。

    key属性允许React Native跟踪这些对象列表,这样它就可以跟踪您正在修改或删除的内容,只需使用特定键删除特定元素。

    这样,就不需要从头开始重建列表。该键将允许React Native将数据对象的定义与屏幕上显示的某些元素联系起来。

    它只允许React Native跟踪我们渲染到屏幕上的不同对象列表。这也是对列表进行更新的性能优化。

        4
  •  2
  •   brownmagik352    8 年前

    @Sarantis Tofas有正确的答案。帮我解决了! 基于评论的另外两个注释:

    1. 如果使用索引,请确保使用索引。toString()否则会收到不同的警告( 失败的子上下文类型-提供给CellRenderer的类型号应为字符串 ).
    2. 如果您没有定义键属性或键提取器,则默认情况下,FlatList将使用索引,但它仍会引发警告。
        5
  •  2
  •   testFireAcc Fire    7 年前

    react native的最佳唯一密钥提取器

    函数如下所示:

      keyExtractor = item => {
        return item.id.toString() + new Date().getTime().toString() + (Math.floor(Math.random() * Math.floor(new Date().getTime()))).toString();  };
    

    或无项目字段:

      keyExtractor = () => {
        return new Date().getTime().toString() + (Math.floor(Math.random() * Math.floor(new Date().getTime()))).toString();  };
    
        6
  •  1
  •   Rotem Shaanan    8 年前

    尝试使用 listkey 而不是 keyExtractor ,它对我有用

        7
  •  1
  •   AmerllicA    6 年前

    事实上,在我的情况下,平面列表 数据 属性值不是数组类型(它是空对象),所以当我添加 keyExtractor={(item, index) => item.key} 它出错了。

    我希望这对你有帮助。

        8
  •  1
  •   Arghya Sadhu Dharmesh    6 年前

    这肯定会有用的。首先生成随机数。

    let generateRandomNum = () => Math.floor(Math.random() * 1001);
    

    然后在需要的地方调用生成随机数。例如:-

    { id: generateRandomNum().toString(), value: 'your value'}
    

    //下面我分享我的一小部分代码,以便更好地理解

    const addGoalHandler = enteredInputGoal => {
    console.log('random nub', generateRandomNum());
    setCourseGoals(courrentGoals => [...courrentGoals, { id: generateRandomNum().toString(), value: enteredInputGoal }]);
      };
    

    最后在平面列表中使用

    <FlatList keyExtractor={(item, index) => item.id} data={courseGoals} renderItem={itemData =>itemData.item.value } />
    
        9
  •  0
  •   Deep Adhia    5 年前

    keyExtractor={(项,索引)=>'键'+索引}对我有用。

        10
  •  0
  •   Ren    4 年前
    keyExtractor ={(item, index) => `${item.key}${index}`}
    

    这对我有用。不需要串联字符串