【问题标题】:React Native - Use a keyExtractor with FlatListReact Native - 使用带有 FlatList 的 keyExtractor
【发布时间】:2018-06-05 19:48:04
【问题描述】:

我得到了:

"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.id 是唯一的)

经过一番谷歌搜索后,我尝试像这样定义一个密钥提取器:

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

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

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

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

【问题讨论】:

  • 试试_keyExtractor = (item, index) =&gt; item.item.key;
  • 希望这是问题所在,当我这样做时,我收到错误“无法读取未定义的属性‘键’”
  • 尝试 _keyExtractor = (item, index) => 索引。它修复了警告吗?如果是,那么问题出在项目键上

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


【解决方案1】:

"VirtualizedList:缺少项的键,请务必指定键 项目上的属性或提供自定义 keyExtractor"

这是列表元素缺少键的警告。这些唯一键允许 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)}
/>

【讨论】:

  • 开始认为这里存在某种错误.. 尝试了这两个选项,但没有运气:(
  • 希望我能提供更多信息,但不知道还能说什么。我知道 key 是独一无二的,但我也尝试了 index 。没有运气
  • 很高兴听到!使用 keyextractor 的方式非常标准。
  • keyExtractor 中的返回索引是完全错误的。如果您的商品没有任何独特之处,最好添加该属性
  • @Akis,我不能改变我的投票,你能编辑你的答案吗?如果没有提供键,反应无论如何都会使用索引。但是没用
【解决方案2】:

我这样做并为我工作:

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

【讨论】:

  • 是的。你需要返回一个string 所以keyExtractor={item =&gt; item.id.toString()} 以防item.id 字段是integer 或其他datatypes 不同于字符串
  • 难以置信的错误答案。在反应中,键可以帮助某种类型的缓存,但是当您使用索引而不是对象的真实表示(如id)时,它会完全打破这一点
  • 据我所知,如果您的数据源中有此 uniq 字符串,则 keyextractor 将获得一个“uniq 字符串提供程序”,您可以像其他说一样使用它: item.key ,当您没有该 uniq 字符串时 ind你必须创造它们!这样你会得到: "key0" , "key1" ...
【解决方案3】:

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

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

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

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

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

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

【讨论】:

    【解决方案4】:

    @Sarantis Tofas 有正确答案。为我解决了! 基于 cmets 的两个附加说明:

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

    【讨论】:

      【解决方案5】:

      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】:

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

        【讨论】:

          【解决方案7】:

          实际上,就我而言,FlatList data 属性值不是数组类型(它是空对象),所以当我添加 keyExtractor={(item, index) =&gt; item.key} 时出错了。

          希望对你有帮助。

          【讨论】:

            【解决方案8】:

            这肯定会奏效。先生成随机数。

            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 中使用

            <FlatList keyExtractor={(item, index) => item.id} data={courseGoals} renderItem={itemData =>itemData.item.value } />
            

            【讨论】:

              【解决方案9】:

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

              【讨论】:

              • 是的,但是项目在 VSCode 中未被使用并标记为黄色。
              【解决方案10】:

              keyExtractor ={(item, index) =&gt; \${item.key}${index}} 这对我有用。不需要连接字符串

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2020-08-17
                • 1970-01-01
                • 1970-01-01
                • 2018-04-05
                • 2018-06-04
                • 1970-01-01
                相关资源
                最近更新 更多