当前位置 博文首页 > react为什么不推荐使用index作为key

    react为什么不推荐使用index作为key

    作者:JQ... 时间:2021-08-21 17:49

    1.旧的虚拟dom和新的虚拟dom对比,首先看他们的key是否相同
    2.相同继续对比他们的内容,不同生成新的真实dom进行替换
    3.如果内容和key都相同,复用旧的真实dom 不做改变

    那么如果我们使用遍历时候自动生成的index作为每个节点的key可能会出现什么问题呢? 下面放个小案例

    首先,初始时我们进行遍历persons

    他会是这样一个过程,源数据

    persons: [
    { id: 1, name: “张三”, age: 15 },
    { id: 2, name: “李四”, age: 16 },
    ],

    生成的真实dom节点

    <ul>
          <li key="0">张三--15</li>
          <li key="1">李四--16</li>
        </ul>
    

    然后我们在这个名单前面插入一个{id:3,name:‘王五',age:14}的数据会变成这样子

    <ul>
       <li key="0">王五--14</li>
          <li key="1">张三--15</li>
          <li key="2">李四--16</li>
        </ul>

    通过上面的更新可以发现 王五将之前张三的key给占用了
    也就是说当我进行更新这一过程首先新的虚拟dom

    <li key="0">王五--14</li>
    

    和旧的虚拟dom

    <li key="0">张三--15</li>
    

    进行比较 新的dom先比较key两人相同,在比较内容一个是王五–14 一个是张三15 ,内容发生变化了,这时就会进行使用新的虚拟dom生成新的真是dom重新渲染页面,而且不仅是之前的张三受影响需要重新生成,后面的李四也要被张三进行替换在生成一个新的内容为张三的真实dom,这样就会导致所有的dom都要重新生成重新渲染,导致性能下降

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
      </head>
      <body>
        <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
        <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
        <script src="https://unpkg.com/babel-standalone@6.26.0/babel.js"></script>
    
        <div ></div>
        <script type="text/babel">
          let root = document.getElementById("root");
          class App extends React.Component {
            constructor(props) {
              super(props);
            }
            state = {
              persons: [
                { id: 1, name: "张三", age: 15 },
                { id: 2, name: "李四", age: 16 },
              ],
            };
            handle = () => {
              const { persons } = this.state;
              const p = {
                id: 0,
                name: "王五",
                age: 14,
              };
              this.setState({
                persons: [p, ...persons],
              });
            };
            render() {
              return (
                <div>
                  <button onClick={this.handle}>点击添加</button>
                  <ul>
                    {this.state.persons.map((person, index) => (
                      <li key={index}>
                        {person.name}--{person.age}
                      </li>
                    ))}
                  </ul>
                </div>
              );
            }
          }
          ReactDOM.render(<App name="hell" />, root);
        </script>
      </body>
    </html>

    试想一下经过上面的推导致,如果我们使用id作为唯一的key值会怎么样呢

    更新前

    <ul>
          <li key="1">张三--15</li>
          <li key="2">李四--16</li>
        </ul>
    

    更新后

    <ul>
       <li key="0">王五--14</li>
          <li key="1">张三--15</li>
          <li key="2">李四--16</li>
        </ul>
    

    这次 虽然王五插入的还是张三的前面但是只对比了一次 王五和上面是否有一样的key=0的节点 ,没有生成新的真实dom进行渲染,而张三和上面key=1的进行对比,发现上面有一个key=1的节点,然后再对比他们的内容是否相同,发现内容也相同,那么就可以复用旧的真实dom,节约性能

    jsjbwy
    下一篇:没有了