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 id="root"></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,节约性能
到此这篇关于react为什么不推荐使用index作为key的文章就介绍到这了,更多相关react index作为key内容请搜索NICE源码以前的文章或继续浏览下面的相关文章希望大家以后多多支持NICE源码!