Open CPPAlien opened 5 years ago
Two assumptions make O(n3) become O(n)
这两条假设看着简单,但理解起来确实让人摸不着头脑。这边的 different types 是指节点不同,比如 <Button> <Image> <Text> 这些。不同的节点,肯定意味着树不同。
<Button> <Image> <Text>
React 采用广度优先的算法,来进行 virtual dom 树的比较。如果一颗树的子节点的 type 都不同,那么比较起来就比较简单,不同的节点就当作不同树进行替换就好。
但如果子节点的 type 有一样的,那要如何区分树相同还是不同呢?
或者当你新增或删除一个相同的子节点时,你知道新增或删除了哪个?
所以此时就需要第二条假设,除了用子节点类型来区分,还可以用一个 key 来区分。所以这边的 key 的主要作用是为了区分不同节点的,只是在用的好的话会带来性能上的优化。
默认会使用 index 作为 key,一般情况下,只要不在子节点的前面和中间位置进行增删操作就没有问题。
有了key属性后,就可以与组件建立了一种对应关系,react根据key来决定是销毁重新创建组件还是更新组件。
key 需要稳定、可预测、并且唯一,不要使用 index 和 随机数作为key,使用随机数作为 key,会导致很多不必要的重建,影响性能。
{this.state.data.map((v,idx)=><Item key={idx} v={v} />)} // 开始时:['a','b','c']=> <ul> <li key="0">a <input type="text"/></li> <li key="1">b <input type="text"/></li> <li key="2">c <input type="text"/></li> </ul> // 数组重排 -> ['c','b','a'] => <ul> <li key="0">c <input type="text"/></li> <li key="1">b <input type="text"/></li> <li key="2">a <input type="text"/></li> </ul>
上面实例中在数组重新排序后,key对应的实例都没有销毁,而是重新更新。具体更新过程我们拿key=0的元素来说明, 数组重新排序后:
在 React 16 之前,如果一个列表中的 key 值相同,则后一个相同 key 值的元素不会被渲染出来。在 React 16 上,key 值相同可以被渲染,但会报一个 warning。
Two assumptions make O(n3) become O(n)
这两条假设看着简单,但理解起来确实让人摸不着头脑。这边的 different types 是指节点不同,比如
<Button> <Image> <Text>
这些。不同的节点,肯定意味着树不同。React 采用广度优先的算法,来进行 virtual dom 树的比较。如果一颗树的子节点的 type 都不同,那么比较起来就比较简单,不同的节点就当作不同树进行替换就好。
但如果子节点的 type 有一样的,那要如何区分树相同还是不同呢?
或者当你新增或删除一个相同的子节点时,你知道新增或删除了哪个?
所以此时就需要第二条假设,除了用子节点类型来区分,还可以用一个 key 来区分。所以这边的 key 的主要作用是为了区分不同节点的,只是在用的好的话会带来性能上的优化。
默认会使用 index 作为 key,一般情况下,只要不在子节点的前面和中间位置进行增删操作就没有问题。
有了key属性后,就可以与组件建立了一种对应关系,react根据key来决定是销毁重新创建组件还是更新组件。
key 需要稳定、可预测、并且唯一,不要使用 index 和 随机数作为key,使用随机数作为 key,会导致很多不必要的重建,影响性能。
上面实例中在数组重新排序后,key对应的实例都没有销毁,而是重新更新。具体更新过程我们拿key=0的元素来说明, 数组重新排序后: