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只能是原始类型,而不能是对象类型

react 列表渲染的更多相关文章

  1. react 入坑笔记(五) - 条件渲染和列表渲染

    条件渲染和列表渲染 一.条件渲染 条件渲染较简单,使用 JavaScript 操作符 if 或条件运算符来创建表示当前状态的元素,然后让 React 根据它们来更新 UI. 贴一个小栗子: funct ...

  2. React 学习(五) ---- 条件和列表渲染

    条件渲染 React中的条件渲染和我们平常写的js 代码一样,都是用的if else, 只不过在if else 中它的返回值是jsx, 根据不同的条件渲染不同的UI. 先写两个组件 //登录的用户显示 ...

  3. angular,vue,react的基本语法—双向数据绑定、条件渲染、列表渲染、angular小案例

    基本语法: 1.双向数据绑定 vue 指令:v-model="msg" react constructor(){ this.state{ msg:"双向数据绑定" ...

  4. React:快速上手(3)——列表渲染

    React:快速上手(3)——列表渲染 使用map循环数组 了解一些ES6 ES6, 全称 ECMAScript 6.0 ,是 JaveScript 的下一个版本标准,2015.06 发版.ES6 主 ...

  5. react 也就这么回事 02 —— JSX 插值表达式、条件渲染以及列表渲染

    我们已经学会了 React 创建元素和渲染元素 ReactDOM.render(<div>Hello React!</div>, document.getElementById ...

  6. react+redux渲染性能优化原理

    大家都知道,react的一个痛点就是非父子关系的组件之间的通信,其官方文档对此也并不避讳: For communication between two components that don't ha ...

  7. 2017.11.7 ant design - upload 组件的使用, react 条件渲染以及 axios.all() 的使用

    一.主要任务:悉尼小程序管理后台,添加景点页面的开发 二.所遇问题及解决 1. 上传多个不同分类音频信息时,如中文音频和英文音频,要求音频不是放在一个数组中的,每个音频是一个独立的字段,此时: < ...

  8. 玩转 React 服务器端渲染

    React 提供了两个方法 renderToString 和 renderToStaticMarkup 用来将组件(Virtual DOM)输出成 HTML 字符串,这是 React 服务器端渲染的基 ...

  9. React 服务器渲染原理解析与实践

    第1章 服务器端渲染基础本章主要讲解客户端与服务器端渲染的概念,分析客户端渲染和服务器端渲染的利弊,带大家对服务器端渲染有一个粗浅认识. 1-1 课程导学1-2 什么是服务器端渲染1-3 什么是客户端 ...

随机推荐

  1. 重构学习day01 类型码 类型码的上层建筑 与类型码相关的重构方法 1.使用子类代替类型码 2.使用状态或策略模式代替类型码

    名词:类型码 类型码的上层建筑 重构方法 1.使用子类代替类型码 2.使用状态/策略模式代替类型码 类中存在方法把某个字段当作条件,根据字段值的不同,进行不同的处理.(自定义概念)则这个字段叫做:类型 ...

  2. Excel - 使用公式将秒转换为分+秒

    场景 现在有个需求:将Excel里的时间转换为分+秒的格式,如下: time(second) time(min+second) 482.712 XXmin,XXs 480.737 XXmin,XXs ...

  3. mysql 安装和修改编码(utf8mb4)

    安装mysql(linux 我的环境centos 7) 安装MySQL官方的Yum Repository wget -i -c http://dev.mysql.com/get/mysql57-com ...

  4. mongodb数据库下载链接,相关配置(转载),官方api

    下载链接:http://dl.mongodb.org/dl/win32/x86_64 配置:http://blog.sina.com.cn/s/blog_685213e70101g81t.html 官 ...

  5. Jasper_crosstab_group_dataset_Error incrementing crosstab dataset

    Error detail: net.sf.jasperreports.engine.JRException: net.sf.jasperreports.engine.JRRuntimeExceptio ...

  6. DB2 错误码解析

    DB2 错误代码大全——SQLSTATE 消息   SQLSTATE 消息本节列示 SQLSTATE 及其含义.SQLSTATE 是按类代码进行分组的:对于子代码,请参阅相应的表. 表 2. SQLS ...

  7. Springboot日志配置探索(主要看logback)(二)

    这篇博客主要是讲在Springboot中扩展的日志框架的配置,也是主要讲logback 8 继续看文档,这里讲到: springboot里面还有几个日志系统框架可以选择使用,你可以通过在classpa ...

  8. 牛客网Java刷题知识点之Java集合类里面最基本的接口有哪些

    不多说,直接上干货! https://www.nowcoder.com/ta/review-java/review?tpId=31&tqId=21086&query=&asc= ...

  9. Windows7获取、更换桌面背景,C#

    使用的API原型是 BOOL SystemParametersinfo(UINT uiAction,UINT uiParam,PVOID pvParam,UINT fWinlni); 在C#中定义如下 ...

  10. Code First约定-数据注释

    通过实体框架Code First,可以使用您自己的域类表示 EF 执行查询.更改跟踪和更新函数所依赖的模型.Code First 利用称为“约定先于配置”的编程模式.这就是说,Code First 将 ...