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
newProps
和 oldProps
+ shallowEqual
newState
和 oldState
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 且为同一个值
注意:
- 不会强制转换类型
- 与 === 不同,=== 将数字 -0 和 +0 视为相等,而将
Number.NaN
与NaN
视为不相等
疑问
- Component 中的 updater 是什么?感觉后续还会有重写!
- PureComponent 中的
Object.assign(pureComponentPrototype, Component.prototype);
是什么作用? - mixed 是什么类型?
- checkShouldComponentUpdate 什么时候调用?