加入收藏 | 设为首页 | 会员中心 | 我要投稿 牡丹江站长网 (https://www.0453zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 运营中心 > 建站资源 > 优化 > 正文

深入理解React的Virtual DOM

发布时间:2019-04-25 10:12:51 所属栏目:优化 来源:Choerodon
导读:React在前端界一直很流行,而且学起来也不是很难,只需要学会JSX、理解State和Props,然后就可以愉快的玩耍了,但想要成为React的专家你还需要对React有一些更深入的理解,希望本文对你有用。 这是Choerodon的一个前端页面 在复杂的前端项目中一个页面可能

▌Case 2:type仍然是相同的字符串,props是不同的。

  1. // before update:  
  2. { type: 'div', props: { className: 'cn' } }  
  3. // after update:  
  4. { type: 'div', props: { className: 'cnn' } } 

由于type仍然代表一个HTML元素,React知道如何通过标准的DOM API调用更改其属性,而无需从DOM树中删除节点。

▌Case 3:type已更改为不同的组件String或从String组件更改为组件。

  1. // before update:  
  2. { type: 'div', props: { className: 'cn' } }  
  3. // after update:  
  4. { type: 'span', props: { className: 'cn' } } 

由于React现在看到类型不同,它甚至不会尝试更新DOM节点:旧元素将与其所有子节点一起被删除(unmount)。因此,在DOM树上替换完全不同的元素的代价会非常之高。幸运的是,这在实际情况中很少发生。

重要的是要记住React使用===(三等)来比较type值,因此它们必须是同一个类或相同函数的相同实例。

下一个场景更有趣,因为这是开发者最常使用React的方式。

▌Case 4:type是一个组件。

  1. // before update:  
  2. { type: Table, props: { rows: rows } }  
  3. // after update:  
  4. { type: Table, props: { rows: rows } } 

你可能会说,“这好像没有任何变化”,但这是不对的。

如果type是对函数或类的引用(即常规React组件),并且启动了树diff比较过程,那么React将始终尝试查看组件内部的所有child以确保render的返回值没有更改。即在树下比较每个组件 - 是的,复杂的渲染也可能变得昂贵!

组件中的children

除了上面描述的四种常见场景之外,当元素有多个子元素时,开发者还需要考虑React的行为。假设有这样一个元素:

  1. // ...  
  2. props: {  
  3.   children: [  
  4.       { type: 'div' },  
  5.       { type: 'span' },  
  6.       { type: 'br' }  
  7.   ]  
  8. },  
  9. // ... 

开发者开发者想将它重新渲染成这样(span和div交换了位置):

  1. // ...  
  2. props: {  
  3.   children: [  
  4.     { type: 'span' },  
  5.     { type: 'div' },  
  6.     { type: 'br' }  
  7.   ]  
  8. },  
  9. // ... 

那么会发生什么?

当React看到里面的任何数组类型的props.children,它会开始将它中的元素与之前看到的数组中的元素按顺序进行比较:index 0将与index 0,index 1与index 1进行比较,对于每对子元素,React将应用上述规则集进行比较更新。在以上的例子中,它看到div变成一个span这是一个情景3中的情况。但这有一个问题:假设开发者想要从1000行表中删除第一行。React必须“更新”剩余的999个孩子,因为如果与先前的逐个索引表示相比,他们的内容现在将不相等。

幸运的是,React有一种内置的方法来解决这个问题。如果元素具有key属性,则元素将通过key而不是索引进行比较。只要key是唯一的,React就会移动元素而不将它们从DOM树中移除,然后将它们放回(React中称为挂载/卸载的过程)。

  1. // ...  
  2. props: {  
  3.   children: [ // 现在react就是根据key,而不是索引来比较了  
  4.     { type: 'div', key: 'div' },  
  5.     { type: 'span', key: 'span' },  
  6.     { type: 'br', key: 'bt' }  
  7.   ]  
  8. },  
  9. // ... 

当状态改变时

(编辑:牡丹江站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!