第7节——渲染列表+Key作用
一、列表渲染
我们再react中如果渲染列表,一般使用map方法进行渲染
import React from "react";export default class LearnJSX2 extends React.Component {state = {infos: [{name: "张三",age: 18,},{name: "李四",age: 20,},{name: "王五",age: 25,},],};render() {return (<div><div>{/*** 使用 map进行列表渲染* map返回要渲染的列表jsx** 使用箭头函数 可以直接return 但是要注意加括号* 并且 括号内 只能有一个根元素*/this.state.infos.map((item, index) => (// 循环的时候必须要在最上层的元素上加key<div key={index}>{item.name} -- {item.age}</div>))}</div></div>);}
}
二、为什么map的时候要加key
1、作用
key是react用来追踪哪些列表的元素被修改,被添加或者是被删除的辅助标示。在开发过程中我们需要保证某个元素的key在其同级元素中具有唯一性。
在react的diff算法中react会借助元素的key来判断该元素是最新创建的还是被移动而来的,从而减少不必要的元素渲染。除此之外,react还要根据key来判断元素与本地状态的关联关系。
2、注意
- key的值一定要和具体的元素一一对应
- 尽量不要用数组中的index来作为key的值
- 当我们在做数组遍历批量生成子节点时,切记同层级的每个子节点的key值不能重复且不会发改变,否则将会产生不可预估的bug
- key改变组件会重新渲染
2、为什么index不能作为key呢?
编写一个列表,点击列表中的每一项进行删除
使用index当做key
import React from "react";export default class LearnJSX3 extends React.Component {state = {arr: ["a", "b", "c", "d"],};delItem(index) {this.state.arr.splice(index, 1);this.setState({arr: this.state.arr,});}render() {return (<div><div>{/* 使用key当做下标*/}{this.state.arr.map((item, index) => (<div onClick={() => this.delItem(index)} key={index}>{item}</div>))}</div></div>);}
}
这么乍一看,好像可以正常实现功能,但是我们通过浏览器的控制台检查列表的渲染后发现,我们删除了一个项,竟然连带着整个列表都进行了重新渲染!
使用item或者其它不会改变的项当做key
import React from "react";export default class LearnJSX3 extends React.Component {state = {arr: ["a", "b", "c", "d"],};delItem(index) {this.state.arr.splice(index, 1);this.setState({arr: this.state.arr,});}render() {return (<div><div>{/* 使用item当做下标*/}{this.state.arr.map((item, index) => (<div onClick={() => this.delItem(index)} key={item}>{item}</div>))}</div></div>);}
}
原因
当我们用index做下标的时候,点击删除列表中的每一项,下标都会发生变化,如果用下标当做key就会触发dom重新渲染。如下图所示。
<!-- newVDom -->
<div><div>b</div> <!-- key==0 --><div>c</div> <!-- key==1 --><div>d</div> <!-- key==2 -->
</div>
<!-- oldVDom -->
<div><div>a</div> <!-- key==0 --><div>b</div> <!-- key==1 --><div>c</div> <!-- key==2 --><div>d</div> <!-- key==3 -->
</div>oldVDom -->
<div><div>a</div> <!-- key==0 --><div>b</div> <!-- key==1 --><div>c</div> <!-- key==2 --><div>d</div> <!-- key==3 -->
</div>