1、key是什么
Keys help React identify which items have changed, are added, or are removed. Keys should be given to the elements inside the array to give the elements a stable identity.
key
是用来帮助 react
识别哪些内容被更改、添加或者删除。key
需要写在用数组渲染出来的元素内部,并且需要赋予其一个稳定的值。稳定在这里很重要,因为如果 key
值发生了变更,react
则会触发 UI
的重渲染。这是一个非常有用的特性。key
就是元素的唯一标识,相当于身份证一样。
2、key的作用
给key
赋值一般采用两种方式,一种是赋值index
(索引),一种是赋值id
(这里用id
表示稳定标识),我们举个例子来看看两者之间的区别。
key=index例子:
ToDo组件:
import React from 'react'import { number, object } from 'prop-types'const ToDo = ({ id, createAt }) => ( <tr> <td> <label>{id}</label> </td> <td> <input /> </td> <td> <label>{createAt.toTimeString()}</label> </td> </tr>)ToDo.propTypes = { id: number.isRequired, createAt: object.isRequired}export default ToDo
ToDoList组件:
import React, { Component } from 'react'import ToDo from '../ToDo'export default class ToDoList extends Component { state = { todoCounter: 1, list: [ { id: 1, createAt: new Date() } ] } addStart = () => { this.setState(prevState => ({ list: [{ id: prevState.todoCounter + 1, createAt: new Date() }, ...prevState.list], todoCounter: prevState.todoCounter + 1 })) } addEnd = () => { this.setState(prevState => ({ list: [...prevState.list, { id: prevState.todoCounter + 1, createAt: new Date() }], todoCounter: prevState.todoCounter + 1 })) } sortEarly = () => { this.setState(prevState => ({ list: prevState.list.sort((a, b) => { return a.createAt - b.createAt }) })) } sortLate = () => { this.setState(prevState => ({ list: prevState.list.sort((a, b) => { return b.createAt - a.createAt }) })) } render () { return ( <div> <code>key=index</code> <br /> <button onClick={this.addStart}>add new to start</button> <button onClick={this.addEnd}>add new to end</button> <button onClick={this.sortEarly}>sorted by earliest</button> <button onClick={this.sortLate}>sorted by latest</button> <table> <tr> <th>ID</th> <th>Input</th> <th>create at</th> </tr> { this.state.list.map((item, index) => ( <ToDo key={index} {...item}></ToDo> )) } </table> </div> ) }}
结果:
key=id例子:
我们将<ToDo key={index} {...item}></ToDo>
改成<ToDo key={item.id} {...item}></ToDo>
,结果为:
我们可以看到key=id
和key=index
时应用程序表现结果是不相同的,不相同之处表现在input
输入值有没有随着排序而改变。我们来解释一下产生这种结果的原因(元素类型相同时,key值相同的元素标识同一个元素)。
当key=index时
当key=id时
一个是元素位置没变,重新渲染数据;一个是位置变了,数据没变,只需要移动位置,所以才导致上面现象。当我们的列表数据非常庞大时,重新渲染的代价是很高的,正确的使用key
值可以帮助我们减少渲染量,做到及时响应,这也是react
的一大优点。
参考:
https://medium.com/@adhithiravi/why-do-i-need-keys-in-react-lists-dbb522188bbb
https://medium.com/@robinpokorny/index-as-a-key-is-an-anti-pattern-e0349aece318
https://zhuanlan.zhihu.com/p/45091185
https://juejin.im/post/5a7c04746fb9a063461fe700
https://juejin.im/post/59abb01c518825243f1b6dad