• React 入门:key 的作用及使用方法技巧


    引题

    先分享两个经典面试题:

    • React / Vue 中的 key 有什么作用?(key 的内部原理是什么?)
    • 为什么遍历列表时,key 最好不要用 index ?

    下面就从针对这两个面试题来了解 key 的作用。

    虚拟 DOM 中 key 的作用

    key 是虚拟 DOM 对象的标识,在更新显示时 key 起着极其重要的作用。

    当状态中的数据发生变化时,React 会根据【新数据】生成【新的虚拟 DOM】,随后 React 进行【新虚拟 DOM】与【旧虚拟 DOM】的 diff 比较。

    比较规则如下:

    1. 旧虚拟 DOM 中找到了与新虚拟 DOM 相同的 key:
    • 如果虚拟 DOM 中内容没变,则直接使用之前的真实 DOM;
    • 如果虚拟 DOM 中内容变了,则生成新的真实 DOM,随后替换掉页面中之前的真实 DOM。
    1. 旧虚拟 DOM 中未找到与新虚拟 DOM 相同的 key:
    • 根据数据创建新的真实 DOM,随后渲染到页面。

    在这里插入图片描述

    使用 index 索引值作为 key

    在这里插入图片描述
    上图中,逆序添加数据后,使得整个列表数据的 index 全部更新,导致旧虚拟 DOM 和新虚拟 DOM 中 key 对应的节点都需要重新生成真实。但数据量很大时,会引发很大效率问题。

    使用 id 唯一标识作为 key

    在这里插入图片描述
    上图中,添加和修改数据后,旧虚拟 DOM 和新虚拟 DOM 中 key 对应的节点内容无更新则无需重新生成真实 DOM (上图中的 小张 );只对新增或被修改的虚拟 DOM 节点生成真实 DOM 并重新渲染。对比 index 索引值作为 key 的案例,使用 id 作为 key 则大大提高了效率。

    用 index 作为 key 可能会引发的问题

    • 若对数据进行:逆序添加、逆序删除等破坏顺序的操作,会产生没有必要的真实 DOM 更新,界面效果没有问题,但效率低。
    • 如果结构中还包含输入类的 DOM,则会产生 DOM 更新错误,界面显示就会有问题。问题演示:在这里插入图片描述
      运行代码如下:
      <!DOCTYPE html>
      <html lang="en">
    
      <head>
        <meta charset="UTF-8">
        <title>key 的作用</title>
      </head>
    
      <body>
        <!-- 准备好一个容器 -->
        <div id="app"></div>
    
        <!-- step01: 引入react核心库 -->
        <script type="text/javascript" src="../js/17/react.development.js"></script>
        <!-- step02: 引入react-dom,用于支持react操作DOM -->
        <script type="text/javascript" src="../js/17/react-dom.development.js"></script>
        <!-- step03: 引入babel,用于将jsx转为js -->
        <script type="text/javascript" src="../js/babel.min.js"></script>
    
        <script type="text/babel"> /* 此处一定要写babel */
    
              class Person extends React.Component {
    
                state = {
                  persons: [
                    {id: 1, name: '小张', age: 18},
                    {id: 2, name: '小李', age: 19},
                  ]
                }
    
                add = () => {
                  const {persons} = this.state
                  const p = {id: persons.length + 1, name: '小王', age: 20}
                  this.setState({persons: [p, ...persons]})
                }
    
                render() {
                  return (
                    <div>
                      <h2>展示人员信息</h2>
                      <button onClick={this.add}>添加一个小王</button>
                      <h3>使用 index 索引值作为 key</h3>
                      <ul>
                        {
                          this.state.persons.map((personObj, index) => {
                            return <li key={index}>{personObj.name} ---- {personObj.age} <input type="text"/></li>
                          })
                        }
                      </ul>
                      <h3>使用 id 数据的唯一标识作为 key</h3>
                      <ul>
                        {
                          this.state.persons.map((personObj, index) => {
                            return <li key={personObj.id}>{personObj.name} ---- {personObj.age} <input type="text"/></li>
                          })
                        }
                      </ul>
                    </div>
                  )
                }
              }
    
              ReactDOM.render(<Person/>, document.getElementById('app'));
          </script>
    
      </body>
    
      </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 注意:如果不存在对数据进行逆序添加、逆序删除等破坏顺序的操作,仅用于渲染列表用于展示,使用 index 作为 key 是没有问题的。

    开发中如何选择 key?

    • 最好使用每条数据的唯一标识作为 key,比如:id、手机号、身份证号、学号等唯一值。
    • 如果确定只是简单的展示数据,用 index 也是可以的。
  • 相关阅读:
    Oracle(2-3) Basic Oracle Net Server Side Configuration
    使用maven 3.8.3 创建并运行java web项目
    分布式事务基础理论
    怎么把产品内容做得更吸引用户?
    React源码分析(三):useState,useReducer
    HC32L110(四) HC32L110的startup启动文件和ld连接脚本
    常见的传输介质及其特性
    JAVA毕业设计开放式教学评价管理系统计算机源码+lw文档+系统+调试部署+数据库
    Monitor Deep Learning Training Progress
    【spring源码系列】之【FactoryBean类型的接口】
  • 原文地址:https://blog.csdn.net/assokoo123/article/details/127762114