写动态子组件时,如果没有给动态子项添加key prop,则会报一个警告:
warning:Each child in an array or iterator should have a unique "key" prop.Check the render method of 'APP'. See .......
这个警告指的是,如果每一个组件是一个数组或迭代器的话,那么必须有一个唯一的key prop。那么这个key prop是做什么的?
1.react利用key来识别组件,它是一种身份标识。keys是react用于追踪哪些列表中元素被修改、被添加或者被移除的辅助标识。
2.react根据key来决定是销毁重新创建组件还是更新组件
key相同,若组件属性有所变化,则react只更新组件对应的属性,没有变化则不更新。
key不同,则react先销毁该组件(有状态组件的componentWillUnmount会执行),然后重新创建该组件(constructor和componentWillUnmount都会执行)
下面我们来根据实际场景思考它的用处。
想象一下,假如需要渲染一个有5000项的成绩排名榜单,而且每隔几秒就会更新一次的排名,其中大部分排名只是位置变了,还有少部分的是完全更新了,少部分则是清出榜单了。
此时key就发挥作用了,它是用来表示当前项的唯一性的props。现在尝试来描述这一场景,下面是一份学生的成绩数组:
[{
sid:'600011',
name:'Tom'
},{
sid:'600012',
name:'Sam'
},{
sid:'600013',
name:'Echo'
}]
其中,sid是学号,name是名字。那么,我们来实现成绩排名的榜单:
import React from 'react';
function Rank({list}){
return (
<ul>
{list.map((entry, index)=>(
<li key={index}>{entry.name}</li>
))}
</ul>
);
}
我们把key设成了序号,这么做的确不会报警告了,但这是非常低效的做法。我们在生产环境下常常犯这样的错,这个key是每次用来做Virtual DOm diff的,每个学生都用序号来更新的问题是它没有和同学的唯一信息相匹配,相当于用了一个随机键,那么不论有没有相同的项,更新都会重新渲染。
正确的做法也可以很简单,只需要把key的内容换成sid就可以了:
import React from 'react';
function Rank({list}){
return (
<ul>
{list.map((entry, index)=>(
<li key={entry.sid}>{entry.name}</li>
))}
</ul>
);
}