https://reactjs.org/docs/lists-and-keys.html#keys

以下代码运行会报错:Warning: Each child in an array or iterator should have a unique 'key' prop.

const arr = [<li>{numbers[0]}</li>,<li>{numbers[0]}</li>,<li>{numbers[1]}</li>]
return (
<ul>{arr}</ul>
);

改成这样子,就不会报错了:

  return (
<ul>
<li>{numbers[0]}</li>
<li>{numbers[0]}</li>
<li>{numbers[1]}</li>
</ul>
);

以上的区别是什么?

  当 渲染一个数组 的时候,必须要为数组中的单元设置一个key属性,这是react的要求。用于让react去跟踪数组元素的增加和删除、移动等,这是key唯一的作用。当元素从数组中读取出来时,react没办法直接跟踪,需要通过key。

对key的要求

要添加在数组item元素的根元素上,而且对于当前数组来说是唯一和稳定的,可以采用如下方式来生成id:

var shortid = require('shortid');
function createNewTodo(text) {
return {
completed: false,
id: shortid.generate(),
text
}
}

key可以使用索引,但不推荐,因为这可能会使列表展示错误的数据,以下来演示一下:

class List extends React.Component{
constructor(props){
super(props)
this.state = {
arr:[9,8,7]
}
this.changeArr = this.changeArr.bind(this);
}
changeArr(){
this.setState((preState)=>{
preState.arr.unshift(10);
return {
arr:preState.arr
}
})
}
render(){
return (
<div>
<button onClick={this.changeArr}>change</button>
<ul>
{this.state.arr.map((item,index) =>
<li key={item}>
{item} <input />
</li>
)}
</ul>
</div>
)
}
}

在线运行:https://codepen.io/gaearon/pen/jrXYRR?editors=0011,以上input的作用是记录dom的状态,可以简单判断dom有没有被重新创建

测试发现规律如下:

不指定key,控制台出现warning,默认以index为key,显式指定key=index,则不报warning,但运行的效果和不指定一样,因为默认都是index为key【这和vue一致,都是默认“就地复用”,以上相同的测试对于vue结果一致】。

当render的时候,对比前后两个虚拟dom,发现key一样则复用这个dom,即刷新后,被复用dom的状态依然和render前一样【以上的input输入的值会保留】

如果key中出现相同的值(假设为5),则第一个key为5的dom会复用之前的dom,而后一个key为5的则创建新的dom

key的作用是跟踪数组中dom的变化,

我提出的问题:

  https://stackoverflow.com/questions/48032286/the-detail-in-react-list-render

  https://segmentfault.com/q/1010000012649420

补充vue的测试代码

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.bootcss.com/vue/2.5.13/vue.js"></script>
</head>
<body>
<div id="root">
<button @click="this.change">change</button>
<div v-for="(item ,index) in arr" :key="item"> {{item}}
<input type="text">
</div>
</div>
</body>
<script>
const vm = new Vue({
el:"#root",
data:{
arr:[1,2,3],
},
methods:{
change:function(){
vm.arr.unshift(1)
}
}
});
</script>
</html>

ps:vue1中出现相同元素,如[1,2,1],会报错,vue2以后不会了,指定的key只能是原始类型,而不能是对象类型

最新文章

  1. Android okHttp网络请求之Get/Post请求
  2. Best Practices for Performance_4.Optimizing Battery Life 获取充电状态、电池信息,&quot;sticky&quot;类型的广播
  3. django安装和卸载
  4. mysqli 操作数据库
  5. POJ 1201 Intervals (差分约束系统)
  6. Oracle中函数/过程返回结果集的几种方式
  7. (转)在SAE使用Apple Push Notification Service服务开发iOS应用, 实现消息推送
  8. Hibernate 、多表关联映射 - 多对多关系映射(many-to-many)
  9. ubuntu配置LAMP
  10. margin三个值
  11. cal日历工具的用法
  12. Scrapy-简单介绍
  13. Linux上删除大量文件几种方式对比
  14. 【python】threadpool的内存占用问题
  15. 直接引用vee-validate校验插件
  16. 手把手教你实现Confluence6.7.1安装与破解
  17. mac ci框架安装使用 memcached存session
  18. ulimit设置内存限制是否有效
  19. PHP: Short URL Algorithm Implementation
  20. 多 LDAP 目录服务器的 FileNet P8 系统介绍和配置实例

热门文章

  1. G - You Are the One(需要重想一遍)
  2. vi/vim打开文件提示Found a swap file by the name
  3. select查询---sql
  4. 部署iis服务器与c#程序遇到的问题小结
  5. 17997 Simple Counting 数学
  6. SSAS 维度属性自定义排序
  7. React 实践记录 03 React router
  8. [转]为ReportViewer导出的PDF文档加上水印
  9. JS中函数与事件
  10. 使用Spring Cloud Feign