想象一下我有这个对象数组
fullList = [
{label: "item A", id="itemA", someBool: true},
{label: "item B", id="itemB", someBool: true},
{label: "item C", id="itemC", someBool: true},
{label: "item D", id="itemD", someBool: false},
{label: "item E", id="itemE", someBool: false},
];
但是我没有在屏幕上呈现完整列表。我正在根据一些过滤器值对其进行过滤,并呈现了一个过滤后的列表。
用户与过滤器进行交互,并将根据他/她选择的过滤器看到不同的过滤列表。
然后,我有两个键选项:
const filteredList = fullList.filter((item) => item.someBool === true);
const filteredListItems = filteredList.map((item,index) =>
<Item_UI_Component
key={item.id} // OPTION #1 - THIS IS ONLY POSSIBLE IF THE FULL LIST CONTAINS id's
key={index} // OPTION #2 - THIS IS ALWAYS POSSIBLE
...SOME OTHER PROPS
/>
);
问题
两种方法的实际区别是什么?我会和他们中的任何一个一起得失吗?如果我像选项#1中那样给元素一个UNIVERSALLY唯一键,React会优化某些东西吗?还是两种情况下的行为都一样?
选项1:
选项2:
filteredList
上始终是唯一的,但是可以使用与上一个渲染器不同的键重新渲染同一元素。注意:如果您未设置任何键,则会收到警告:
警告:列表中的每个孩子都应该有一个唯一的“关键”道具。有关更多信息,请参见https://reactjs.org/docs/lists-and-keys.html#keys。
答案 0 :(得分:1)
摘自官方文档:
https://reactjs.org/docs/lists-and-keys.html
当您没有呈现项目的稳定ID时,可以将项目索引用作最后的选择。如果项目的顺序可能更改,我们不建议使用索引作为键。这可能会对性能产生负面影响,并可能导致组件状态出现问题。
正如我在评论中所说:
原因是因为如果您的过滤器发生变化,并且现在位于索引2处的项目与以前位于索引2处的项目不同,则存在非常真实的风险,即React会变得混乱而不是呈现一个新的组件,它将只更改发送该组件的道具,并且根据您的编码方式,它可能根本不会在视觉上进行更新。
使用索引作为键之前,我肯定遇到了问题
答案 1 :(得分:1)