React 源码(一)Component & PureComponent

React 对象

在 React 项目中 /packages/react/index.js 可以看到 React 导出的对象

Component & PureComponent

/package/react/src/ReactBaseClasses.js 可以看到 Component 和 PureComponent 的定义。

Component

function Component(props, context, updater) {
  this.props = props;
  this.context = context;
  this.refs = emptyObject;
  this.updater = updater || ReactNoopUpdateQueue;
}

Component.prototype.isReactComponent = {};
Component.prototype.setState = function(partialState, callback) {
  this.updater.enqueueSetState(this, partialState, callback, 'setState'); // ??? enqueueSetState 
};
Component.prototype.forceUpdate = function(callback) {
  this.updater.enqueueForceUpdater(this, callback, 'forceUpdate'); // ??? enqueueForceUpdater
}

PureComponent

function ComponentDummy() {}
ComponentDummy.prototype = Component.prototype;

function PureComponent(props, context, updater) {
  this.props = props;
  this.context = context;
  this.refs = emptyObject;
  this.updater = updater || ReactNoopUpdateQueue;
}

const pureComponentPrototype = (PureComponent.prototype = new ComponentDummy()); // PureComponent.prototype.__proto__ === Component.prototype
pureComponentPrototype.constructor = PureComponent; // PureComponent.prototype.constructor = PureComponent
Object.assign(pureComponentPrototype, Component.prototype); // ???
pureComponentPrototype.isPureReactComponent = true;

PureComponent 继承了 Component prototype 上的所有方法和属性,并且 PureComponent 的 prototype 上有 isPureReactComponent 属性值为 true。

isPureReactComponent

在 React 源码中全局搜索 prototype.isPureReactComponent 即可找到 /packages/react/react-reconciler/src/ReactFiberClassComponent.new.js

function checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext) { // ??? checkShouldComponentUpdate 什么时候调用
  const instance = workInProgress.stateNode;
  if(typeof instance.shouldComponentUpdate === 'function') {
    const shouldUpdate = instance.shouldComponentUpdate(newProps, newState, newxtContext);
    return shouldUpdate;
  }
  if(ctor.prototype && ctor.prototype.isPureReactComponent) {
    return (!shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState)); // ??? shallowEqual()
  }
  return true;
}

从代码中可以看出如果是 PureComponent,那么则会去 shallowEqual newPropsoldProps + shallowEqual newStateoldState

shallowEqual

const hasOwnProperty = Object.prototype.hasOwnProperty;
function shallowEqual(objA: mixed, objB: mixed): boolean {
  if(is(objA, objB)) { // ??? is()
    return true;
  }
  if(typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
    return false;  
  }
  const keysA = Object.keys(objA);
  const keysB = Object.keys(objB);
  
  if(keysA.length !== keysB.length) {
    return false;
  }
  
  for(let i = 0; i < keysA.length; i++) {
    if(!hasOwnProperty.call(objB, keysA[i]) || is(objA[keysA[i]], objB[keysA[i]])) {
      return false;
    }
  }
  
  return true;
}

is

function is(x: any, y: any) {
  return ((x === y && (x !== 0 || 1 / x === 1 / y)) || (x !== x && y !== y));
}

const objectIs: (x: any, y: any) => boolean = typeof Object.is === 'function' ? Object.is : is;

export default objectIs;

Object.is

判断两个值是否为同一个值,如果满足一下条件则两个值相等

  • 都是 undefined
  • 都是 null
  • 都是 true 或 false
  • 都是相同长度的字符串且相同字符按相同顺序排列
  • 都是相同对象(意味着每个对象有同一个引用)
  • 都是数字,且
    • 都是 +0
    • 都是 -0
    • 都是 NaN
    • 或都是非零而且非 NaN 且为同一个值

注意:

  1. 不会强制转换类型
  2. 与 === 不同,=== 将数字 -0 和 +0 视为相等,而将 Number.NaNNaN 视为不相等

疑问

  1. Component 中的 updater 是什么?感觉后续还会有重写!
  2. PureComponent 中的 Object.assign(pureComponentPrototype, Component.prototype); 是什么作用?
  3. mixed 是什么类型?
  4. checkShouldComponentUpdate 什么时候调用?

你可能感兴趣的:(React 源码(一)Component & PureComponent)