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

深入理解React的Virtual DOM

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

即使Message被关闭了(不再显示),props.children父母div仍将拥有三个元素,children[0]具有一个值false(布尔类型)。还记得true/false, null甚至undefined都是Virtual DOM对象type属性的允许值吗?浏览器最终得到类似这样的东西:

  1. // ...  
  2. props: {  
  3.   children: [  
  4.     false, //  isShowMessage && <Message /> 短路成了false  
  5.     { type: Table },  
  6.     { type: Footer }  
  7.   ]  
  8. }  
  9. // ... 

所以,不管Message是否被显示,索引都不会改变,Table仍然会和Table比较,但仅仅比较Virtual DOM通常比删除DOM节点并从中创建它们要快得多。

现在来看看更高级的东西。开发者喜欢HOC。高阶组件是一个函数,它将一个组件作为一个参数,添加一些行为,并返回一个不同的组件(函数):

  1. function withName(SomeComponent) {  
  2.   return function(props) {  
  3.     return <SomeComponent {...props} name={name} />;  
  4.   }  

开发者在父render方法中创建了一个HOC 。当React需要重新渲染树时,React 的Virtual DOM将如下所示:

  1. // On first render:  
  2. {  
  3.   type: ComponentWithName,  
  4.   props: {},  
  5. }  
  6. // On second render:  
  7. {  
  8.   type: ComponentWithName, // Same name, but different instance  
  9.   props: {},  

现在,React只会在ComponentWithName上运行一个diff算法,但是这次同名引用了一个不同的实例,三等于比较失败,必须进行完全重新挂载。注意它也会导致状态丢失,幸运的是,它很容易修复:只要返回的实例都是同一个就好了:

  1. // 单例  
  2. const ComponentWithName = withName(Component);  
  3. class App extends React.Component() {  
  4.   render() {  
  5.     return <ComponentWithName />;  
  6.   }  

修复update

现在浏览器已经确保不会重新装载东西了,除非必要。但是,对位于DOM树根目录附近的组件所做的任何更改都将导致其所有子项的进行对比重绘。结构复杂,价格昂贵且经常可以避免。

如果有办法告诉React不要查看某个分支,那将是很好的,因为它没有任何变化。

这种方式存在,它涉及一个叫shouldComponentUpdate的组件生命周期函数。React会在每次调用组件之前调用此方法,并接收props和state的新值。然后开发者可以自由地比较新值和旧值之间的区别,并决定是否应该更新组件(返回true或false)。如果函数返回false,React将不会重新渲染有问题的组件,也不会查看其子组件。

通常比较两组props和state一个简单的浅层比较就足够了:如果顶层属性的值相同,浏览器就不必更新了。浅比较不是JavaScript的一个特性,但开发者很多方法来自己实现它,为了不重复造轮子,也可以使用别人写好的方法。

在引入浅层比较的npm包后,开发者可以编写如下代码:

  1. class TableRow extends React.Component {  
  2.   shouldComponentUpdate(nextProps, nextState) {  
  3.     const { props, state } = this;  
  4.     return !shallowequal(props, nextProps)  
  5.            && !shallowequal(state, nextState);  
  6.   }  
  7.   render() { /* ... */ }  

但是你甚至不必自己编写代码,因为React在一个名为React.PureComponent的类中内置了这个功能,它类似于React.Component,只是shouldComponentUpdate已经为你实现了浅层props/state比较。

(编辑:晋中站长网)

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

热点阅读