React hooks系列 页面渲染时的key值
前言
react
的渲染列表时要带上Key
一直是面试的高频考点。
但我们往往使用它是为了使控制台中的警告消失,却忽略了key
使用不当带来性能上的问题。
以下主要从三方面去讲解key
。
目录
一、 key
的作用
二、 key
带来的性能问题
三、 如何正确的使用key
一、key
的作用
key的作用:在渲染的时候告诉React每个组件
或者JSX标签
对应于哪个数组项,以便后面的操作可以匹配上它们。如果数组项需要移动(例如由于排序)、插入或删除,它作为唯一标识就变得很重要。
一个独一无二的的key
可以帮助React
辨别接下来到底发生了什么,并对DOM树
进行正确的更新。
上面讲述可能有点抽象,来个易懂例子:
想象一下桌面上的文件没有名称。取而代之的是,您需要提前把他们排好 - 第一个文件,第二个文件等。
刚开始是可以知道各自文件里的内容,但是删除文件后,它将变得令人困惑。第二个文件将成为第一个文件,第三个文件将是第二个文件,依此类推这样再往复几轮这种新增、删除和排序的操作,就彻底分不清哪些文件对应哪些内容了。
文件夹中的文件名和数组中数据项的key
具有类似的目的。key
让我们独特地识别其相邻数据项之间的关系。即使该位置因重新排序而变化,key
也可以在React整个生命周期中识别该数据项。
二、key
带来的性能问题
有时候往往我们数组的数据项中找不到唯一的key
值,我们往往会通过map中的index
作为key
,
实际上,这根本就不是指定一个key
,即使react在没有key
的时,它自己内部其实就是使用的index
作为key
,但好处就是清除了控制台的报错。
想象下,如果数据插入,删除或重新排序,则渲染数据项的顺序将随着时间的推移而变化。这使得index
作为key
会导致微妙而令人困惑的bug。
为什么 ? 因为用index
作为key
它是动态的(数组的删除、更新和排序,index
对每个数据项来说作为key
都是一直在变化的)。
这使得渲染时的key
总是不匹配,导致每次都要重新创建所有组件
和DOM
。这不仅会减慢速度,而且还会丢失列表项中的任何用户输入。
三、如何正确的使用key
- 在数组中
key
在每个数据项之间必须唯一。但是,它允许在不同的数组中,数据项key
可以相同。
const a = [{key:0,val:a1},{key:1,val:a2}]
const b = [{key:0,val:b1},{key:1,val:b2}]
-
我们得到一个要渲染的数组对象时,如果没有很好的
key
作为唯一条件,则应该在渲染前对数据处理好。 -
如果是普通的数组,并且数据不会重新排序、新增和修改这种情况,我们是可以使用
index
作为索引的。
const array = {
lines: [
'apple',
'pear',
'banana'
]
};
export default function frust() {
return (
<>
{array.lines.map((line, index) =>
<p key={index}>
{line}
</p>
)}
</>
);
}
-
除了上述情况,不要在渲染的时候生成
key
比如index
,index
作为key
不稳定,破坏了key
的用途。 -
在最顶层的标签使用
key
export default function frust() {
return (
<>
{array.lines.map((line, index) =>
<div key={line.id}>
//不应该在p中使用key
<p>
{line}
</p>
</div>
)}
</>
);
}
注意
如果把key
当做prop
传给子组件不能使用 key={line.id}
,这是错误的,正确的是keyItem={line.id}
。
export default function frust() {
return (
<>
{array.lines.map((line,) =>
此时index不能传递到Category
<Category key={line.id}>
<p>
{line}
</p>
</Category>
)}
</>
);
}
结尾
至此关于react
的key
内容暂告一段落。