react中key的使用

29次阅读

共计 2369 个字符,预计需要花费 6 分钟才能阅读完成。

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=idkey=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

正文完
 0