最近在看一本名叫《深刻浅出React和Redux》这一书,里面谈到了react的dom更新比对,记录一下。javascript
假设有这么一个组件java
<ul> <ListItem text="first" /> <ListItem text="second" /> <ListItem text="third" /> </ul>
如今,咱们在这个组件的前面插入一个新的组件<ListItem text='zero' />
react
<ul> <ListItem text="zero" /> <ListItem text="first" /> <ListItem text="second" /> </ul>
思考,怎么更新dom是最优的,react是去怎么更新?数组
按照咱们的思惟,最优的更新dom就是去把新增一个
ListItem
组件,放在第一个。把以前的第一个组件<ListItem text="first" />
以及第二个组件<ListItem text="second" />
日后挪一位。这样的结果是最好的。dom
但是react不是这样更新的!函数
它先去比较第一个
ListItem
组件,发现组件上的text
值first
变成了zero
,须要更新。第二个组件text
以前的second
变成了first
,也须要更新,最后新建立一个组件,把它的text
设置为second
。react就完成了它的更新。code
在 React 的眼里,肯定每个组件在组件序列中的惟一标识就是它的位置,因此
它也彻底不懂哪些子组件实际上并无改变,为了让 React 更加“聪明”,就须要开发者
提供一点帮助。ip
若是在代码中明确地告诉 React 每一个组件的惟一标识,就能够帮助 React 在处理这个
问题时聪明不少,告诉 React 每一个组件“身份证号”的途径就是 key 属性。开发
<ul> <ListItem key={1} text="first" /> <ListItem key={2} text="second" /> <ListItem key={3} text="third" /> </ul>
如今再去插入一个ListItem
组件放在最前面,让它key为0
it
<ul> <ListItem key={0} text="zero" /> <ListItem key={1} text="first" /> <ListItem key={2} text="second" /> </ul>
如今,react根据key值,知道了第二个第三个组件是以前的第一个第二个,因此react会建立一个ListItem
组件放在第一位,对于原有的两个组件只用原有的props触发更新。这里就须要组件内部的shouldComponentUpdate
的钩子函数进行判断来减小没必要要的更新。
可是这个 key 值只是惟一还不足够,这个 key 值还须要是稳定不变的,试想,若是
key 值虽然可以在每一个时刻都惟一,可是变来变去,那么就会误导 React 作出错误判断,
甚至致使错误的渲染结果。
<ul> { Arr.map((item,index)=>(<ListItem key={index} text={item.text} />)) } </ul>
用数组下标做为 key ,看起来 key 值是惟一的,可是却不是稳定不变的,随着 Arr
数组值的不一样,一样一个Listltem
实例在不一样的更新过程当中在数组中的下标彻底可能不
同,把下标当作 key 就让 React 完全乱套了。
须要注意,虽然 key 是一个 prop ,可是接受 key 的组件并不能读取到 key 的值,由于key
ref
React 保留的两个特殊 prop ,并无预期让组件直接访问。