基于密钥的优化(kbo)和shouldComponentUpdate(scu)如何相互关联?
他们似乎在做同样的事情(避免重新渲染和区分)。
他们有什么不同?我错过了什么吗?
我的感觉是scu被“包含”在基于密钥的优化中,即。如果一个节点具有与之前渲染相同的键 - 在树的同一路径上 - 那么它将不会被重新渲染,这也可以通过kbo实现,但我不确定。
如果某个节点的路径与前一个渲染中的任何路径不匹配且scu返回false会发生什么情况,那么该节点是否会重新渲染?我的猜测是肯定的,但不确定。
答案 0 :(得分:3)
他们肯定不一样。
shouldComponentUpdate
控制是否应运行render
,即DOM diff和update是否必要。当props
,state
或context
发生更改时,通常会进行此检查。
钥匙非常不同。通过使用相同的key
,可以确保使用相同的组件实例。请考虑以下事项:
<MyComponent title="Title 1" />
<MyComponent title="Title 2" />
如果由于某种原因,您的render
删除了第一个组件,最后会:
<MyComponent title="Title 2" />
然后会发生的是第二个组件从DOM中删除,第一个组件获得不同的属性,导致重新渲染和DOM更新。
如果您正确使用了密钥:
<MyComponent key="key1" title="Title 1" />
<MyComponent key="key2" title="Title 2" />
删除第一个组件后,第二个组件将收到相同的道具(将根据其shouldComponentUpdate
重新呈现)但很可能唯一的DOM更新是删除第一个组件。
感谢key
,React可以进行最小的DOM更新。
这有一些严重的影响,例如在使用非托管组件时:
const MyComponent = () => {
return <input defaultValue="some-text" />;
};
再次,当我们
时<MyComponent title="Title 1" />
<MyComponent title="Title 2" />
然后在第一个组件的input
中写入一些文本,然后删除该组件,即使文本是包含它的第二个组件,文本也会保留在<input>
中。密钥可以防止这种情况。
另请注意,将key
设置为之前未呈现的内容时,例如:
<MyComponent key="key3" />
创建MyComponent
的新实例,调用componentDidMount
。
这可用于完全重置组件的状态(例如,对于非托管输入)。
大多数情况下,您只需要在列表中使用key
,以便在排序,删除等时提供性能提升。它具有非托管输入的一些次要用途,但仅此而已。
要与shouldComponentUpdate
进行比较,基于键的优化有助于将当前渲染状态与前一渲染状态相匹配,从而防止道具被更改。