ReactBaseClasses.js
该文件声明了Component和PureComponent
Component
/**
* Base class helpers for the updating state of a component.
*/
function Component(props, context, updater) {
this.props = props;
this.context = context;
// If a component has string refs, we will assign a different object later.
this.refs = emptyObject;
// We initialize the default updater but the real one gets injected by the
// renderer.
this.updater = updater || ReactNoopUpdateQueue;
}
setState
* @param {object|function} partialState Next partial state or function to
* produce next partial state to be merged with current state.
* @param {?function} callback Called after state is updated.
* @final
* @protected
*/
Component.prototype.setState = function(partialState, callback) {
invariant(
typeof partialState === 'object' ||
typeof partialState === 'function' ||
partialState == null,
'setState(...): takes an object of state variables to update or a ' +
'function which returns an object of state variables.',
);
this.updater.enqueueSetState(this, partialState, callback, 'setState');
};
第一个参数必须是对象、函数或者null,否则执行invariant就会报错。 第二个参数是state更新之后的回调函数。
- 不能确保当前的组件的state立刻更新,所以紧接着使用的state可能是旧值。
- 不能确保setState是同步的,可能是之后统一调用的,想要使用更新后的state的解决方式是提供更新后的回调函数。
- 当提供一个函数fn给setState时,fn将在之后的某个时刻被调用(异步)。 fn将与最新的 组件参数一起调用(state, props, context)。 这些参数(state, props, context)可能与this.*不同,因为fn可能在receiveProps之后但shouldComponentUpdate生命周期之前被调用,新的state, props, context还没有分配到this(当前组件)上。
forceUpdate
Component.prototype.forceUpdate = function(callback) {
this.updater.enqueueForceUpdate(this, callback, 'forceUpdate');
};
callback是强制更新之后的后调
- forceUpdate可以强制唤起组件更新流程
- shouldComponentUpdate生命周期不再调用,componentWillUpdate和componentDidUpdate依旧有效
PureComponent
PureComponent的实现的理解请看注释,如有错误,还望指正!
function ComponentDummy() {}
// 继承Component的原型
ComponentDummy.prototype = Component.prototype;
function PureComponent(props, context, updater) {
this.props = props;
this.context = context;
// If a component has string refs, we will assign a different object later.
this.refs = emptyObject;
this.updater = updater || ReactNoopUpdateQueue;
}
/* pureComponentPrototype实际是PureComponent原型的地址,
并初始化PureComponent的原型为ComponentDummy的一个实例,
因为ComponentDummy的原型就是Component的原型,
因此间接使得PureComponent的原型的__proto__ 是Component的原型
(个人感觉是为了使得PureComponent instanceof Component结果为true)
*/
const pureComponentPrototype = (PureComponent.prototype = new ComponentDummy());
// 使得PureComponent原型的constructor指向本身
pureComponentPrototype.constructor = PureComponent;
// PureComponent的原型中添加Component原型中的可枚举属性
// 目的是为了减少原型查找
Object.assign(pureComponentPrototype, Component.prototype);
pureComponentPrototype.isPureReactComponent = true;