React Native - 使用带FlatList的keyExtractor

时间:2017-12-23 15:23:47

标签: arrays react-native react-native-flatlist

我一直在接受:

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

相当混乱......,我传递的数组有一个在数组中每个对象中定义的键属性。我在this.state中定义了该数组。我在控制台中快速打印出来以确定: print out of array

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

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

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

经过一些谷歌搜索后,我尝试定义一个Key Extractor,如下所示:

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

然后这是我的平面列表定义:

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

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

9 个答案:

答案 0 :(得分:27)

  

&#34; VirtualizedList:缺少项目的密钥,请务必指定密钥   项目上的属性或提供自定义keyExtractor&#34;

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

您必须选择一个唯一的关键道具,例如idemail

keyExtractor默认使用index。但警告仍然可见。

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

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

Flatlist组件应如下所示:

<FlatList
  style={{}}
  data={this.state.FeedDataCollection}
  keyExtractor={(item, index) => item.key}
  renderItem={(rowData) =>this.RenderFeedCard(rowData)}
/>

答案 1 :(得分:7)

我这样做并为我工作:

keyExtractor={(item, index) => 'key'+index}

答案 2 :(得分:2)

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

  1. 如果您使用index,请确保使用index.toString(),否则您将收到不同的警告(失败的子上下文类型 - 提供给CellRenderer期望字符串的类型编号)。 / LI>
  2. 如果您没有定义键属性或keyExtractor,FlatList将默认使用索引,但它仍然会发出警告。

答案 3 :(得分:1)

实际上,在我的情况下,FlatList data 属性值不是数组类型(它是空对象),因此当我添加keyExtractor={(item, index) => item.key}时会出错。

希望对您有帮助。

答案 4 :(得分:0)

尝试使用listkey代替keyExtractor,它对我有用

答案 5 :(得分:0)

用于响应本机的最佳唯一密钥提取器

功能如下:

  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 :(得分:0)

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

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

我们不希望React Native仅仅因为对数据数组的微小更改而重建整个列表。理想情况下,我们希望React Native能够专门检测我们删除或更改的对象并相应地进行更新,但是如果不提供密钥,那将不会发生。

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

这样,无需从头开始重建列表。该键将使React Native可以将数据对象的定义与屏幕上出现的某些元素相关联。

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

答案 7 :(得分:0)

这可以肯定。首先生成随机数。

{
    nom:'Kox', 
    prenom:'Karl', 
    gender:'M', 
    addres: 
        {
          rue: '123 Fake Street', 
          appt:108, 
          city:'mycity',
          zip_code:'GGG23'
        }, 
    class: 
        {
          name:'CLASS ONE', 
          group:'C', 
          section:'SECTION ONE' 
        }

}

然后在需要的地方致电以生成随机数。像:-

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

//下面我分享一小部分代码以更好地了解

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

最后在FlatList中使用

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

答案 8 :(得分:0)

keyExtractor={(item, index) => 'key'+index} 对我有用。