react中使用index作为key值会怎样?

key

写动态子组件的时候,如果没有给动态子项添加 key prop,则会报一个警告:

Warning: Each child in an array or iterator should have a unique "key" prop. Check the render method 
of 'App'. See https://fb.me/react-warning-keys for more information. 

这个警告指的是,如果每一个子组件是一个数组或迭代器的话,那么必须有一个唯一的 key prop。
这个 key prop 究竟是做什么的呢?

组件性能优化

我们想象一下,假如需要渲染一个有 5000 项的成绩排名榜单,而且每隔几秒就会更新一次
排名,其中大部分排名只是位置变了,还有少部分的是完全更新了,少部分则是清出榜单了。
此时 key 就发挥作用了,它是用来标识当前项的唯一性的 props。现在尝试来描述这一场景,
我们有一份学生的成绩数组:

[{
    
     
 sid: '600211', 
 name: 'Cam', 
}, {
    
     
 sid: '600243', 
 name: 'Arcthur', 
}, {
    
     
 sid: '600225', 
 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> 
 ); 
} 

当 key 相同时,React 会怎么渲染呢?答案是只渲染第一个相同 key 的项,且会报一个警告:

Warning: flattenChildren(): Encountered two children with the same key, `.$a`. Child keys must be unique; 
when two children share a key, only the first child will be used. 

因此,对 key 有一个原则,那就是独一无二,且能不用遍历或随机值就不用,除非列表内容
也并不是唯一的表示,且没有可以相匹配的属性。
关于 key,我们还需要知道的一种情况是,有两个子组件需要渲染的时候,我们没法给它们
设 key。这时需要用到 React 插件 createFragment 来解决:

import React from 'react'; 
import createFragment from 'react-addons-create-fragment'; 
function Rank({
    
     first, second }) {
    
     
 const children = createFragment({
    
     
 first: first, 
 second: second, 
 }); 
 return ( 
 <ul> 
 {
    
    children} 
 </ul> 
 ); 
} 

上述代码中,first 和 second 两个 prop 的 key 就是我们设置对象的 key。

猜你喜欢

转载自blog.csdn.net/weixin_45416217/article/details/113136380