Skip to content

Latest commit

 

History

History
78 lines (65 loc) · 2.69 KB

pureRenderMixin.md

File metadata and controls

78 lines (65 loc) · 2.69 KB

PureRenderMixin

React的渲染函数式纯函数(当传给它同样的props和state,它渲染出同样的效果),所以部分场景下可以利用一些插件来提升性能。

如果更新的props和旧的一样,这个时候很明显UI不会变化,但是React还是要进行虚拟DOM的diff,这个diff就是多余的性能损耗,而且在DOM结构比较复杂的情况,整个diff会花费较长的时间。

侧重的优化点是UI需不需要更新。

ES6中的写法

import PureRenderMixin from 'react-addons-pure-render-mixin';
class FooComponent extends React.Component {
      constructor(props) {
        super(props);
        this.shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate.bind(this);
      }

      render() {
        return <div className={this.props.className}>foo</div>;
      }
}

PureRenderMixin的原理就是它扩展了shouldComponentUpdate,在shouldComponentUpdate内它比较当前的props、state和接下来的props、state,当两者相等的时候返回false,这样组件就不会进行虚拟DOM的diff。

这里需要注意

PureRenderMixin内进行的仅仅是浅比较对象。如果对象包含了复杂的数据结构,深层次的差异可能会产生误判。仅用于拥有简单props和state的组件。

源码

'use strict';
var shallowCompare = require('./shallowCompare');
var ReactComponentWithPureRenderMixin = {
  shouldComponentUpdate: function (nextProps, nextState) {
    return shallowCompare(this, nextProps, nextState);
  }
};
module.exports = ReactComponentWithPureRenderMixin;

shallowCompare方法

'use strict';
var shallowEqual = require('fbjs/lib/shallowEqual');
function shallowCompare(instance, nextProps, nextState) {
  return !shallowEqual(instance.props, nextProps) || !shallowEqual(instance.state, nextState);
}
 
module.exports = shallowCompare;

shallowEqual方法(比较两个对象是否相等,递归度为1)

function shallowEqual(objA, objB) {
  if (objA === objB) {  //检查对象引用的相等性
    return true;
  }
  if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
    return false;
  }
  var keysA = Object.keys(objA);//返回对象可被枚举的属性
  var keysB = Object.keys(objB);
  if (keysA.length !== keysB.length) {
    return false;
  }
  // Test for A's keys different from B.
  var bHasOwnProperty = hasOwnProperty.bind(objB);// bHasOwnProperty(xx) === objB.hasOwnProperty(xx)
  for (var i = 0; i < keysA.length; i++) {
    if (!bHasOwnProperty(keysA[i]) || objA[keysA[i]] !== objB[keysA[i]]) {
      return false;
    }
  }
  return true;
}
 
module.exports = shallowEqual;