# Key 的优化

我们在遍历列表时,总是会提示一个警告,让我们加入一个 key 属性。这和我们修改数据后 React 的重新渲染有关系。

1. 情况一:在最后位置插入数据

  • 这种情况,有无 key 意义不大。

2. 情况二:在前面插入数据

  • 这种情况,在没有 key 的情况下,所有的 li 都需要进行修改。

3. 当子元素(这里以 li 为例子)拥有 key 时,React 使用 key 来匹配原有树上的子元素以及最新树上的子元素

  • 如果原来树上有元素 A,B,C,D,新数则是将新元素 E 插入 B 和 C 之间,新树元素为 A,B,E,C,D,在 li 拥有 key 的情况下 (这里将元素的名称作为它们的 key),key 为 C 和 D 的元素仅仅只是进行位移,不需要进行任何其他的修改,然后将 key 为 E 的元素插入到 C 元素前面的位置即可。
  • 如果 li 没有 key,则从 B 元素开始,后面的所有 li 都需要进行修改。

4.key 的注意事项

  • key 应该是唯一的
  • key 不要使用随机数(随机数在下一次 render 时,会重新生成一个数字,导致新旧树在匹配 key 的时候无法对应上)
  • 使用 index 作为 key,对性能时没有优化的

5.React 对 diff 算法进行优化,将其优化成了 O (n)

  • 同层节点之间相互比较,不会跨节点比较
  • 不同类型的节点,产生不同的树结构
  • 开发时,可以通过 key 来指定哪些节点在不同的渲染下保持稳定

# SCU 优化

通过 shouldComponentUpdate,在 shouldComponentUpdate 这生命周期中判断当前的 state 和 props 是否和更新后的 state 和 props 是否发生改变,来决定是否要调用 render 函数进行更新重新渲染。

# 以 index 作为 key,删除是删除最后一个

react 使用 map 生成的元素,key 的设定不对导致每次删除都删除最后一个。假设你的 key 设置为 map 中的索引,假设为 0,1,2(原 dom 树),现在你用 splice 删除掉 1,重新渲染时,还是会按 map 索引按顺序渲染为 0,1(新 dom 树),由于 react 渲染机制是比较的 key 值,发现 key(0,1)都没变,所以保留原 dom 树的 0,1 元素(包括里面内容都不变),而由于数量少了一个,渲染的最后一个就没有渲染,就感觉是删除的最后一个。

主要是比较不同的是通过 key 进行对比,如果 key 是 index,删除后重新渲染后 index 顺序是保持不变的,只有数量是可能发生改变,所有 key 通过对比后,前面的一直都没问题,只有到最后没有新的虚拟 DOM 的 index 相对于旧的虚拟 DOM 的 index 少了,所以相对于之前的 DOM 树就少渲染一个元素,看起来就像是删除了最后一个元素。