设为首页 - 加入收藏 ASP站长网(Aspzz.Cn)- 科技、建站、经验、云计算、5G、大数据,站长网!
热搜: 重新 试卷 文件
当前位置: 首页 > 运营中心 > 建站资源 > 优化 > 正文

深入理解React的Virtual DOM(5)

发布时间:2019-04-24 21:27 所属栏目:21 来源:Choerodon
导读:因此,你可以添加唯一键(但在这种特殊情况下使用key不是最佳选择)或者采用更智能的trick:使用 的布尔短路运算,这是JavaScript和许多其他现代语言的一个特性。像这样: div {isShowMessageMessage/} Table/ Foot

因此,你可以添加唯一键(但在这种特殊情况下使用key不是最佳选择)或者采用更智能的trick:使用 && 的布尔短路运算,这是JavaScript和许多其他现代语言的一个特性。像这样:

  1. <div>  
  2.   {isShowMessage && <Message />}  
  3.   <Table />  
  4.   <Footer />  
  5. </div> 

即使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比较。

(编辑:ASP站长网)

网友评论
推荐文章
    热点阅读