React 源码阅读-10
ReactBaseClasses
这个文件是export
出了Component
, PureComponent
export {Component, PureComponent};
源码+注释
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
//生产环境使用,为了抛出错误信息
import invariant from 'shared/invariant';
//只在开发环境有效,使用 console.warn(message);
import lowPriorityWarning from 'shared/lowPriorityWarning';
//没有传入参数updater参数时,this.updater的值就是ReactNoopUpdateQueue
//用于报警告的 可以忽略
import ReactNoopUpdateQueue from './ReactNoopUpdateQueue';
const emptyObject = {};
if (__DEV__) {
Object.freeze(emptyObject);
// Object.freeze() 方法可以冻结一个对象。一个被冻结的对象再也不能被修改;冻结了一个对象则不能向这个对象添加新的属性,不能删除已有属性,不能修改该对象已有属性的可枚举性、可配置性、可写性,以及不能修改已有属性的值。此外,冻结一个对象后该对象的原型也不能被修改。freeze() 返回和传入的参数相同的对象
}
/**
* Base class helpers for the updating state of a component.
*/
// Base class用于更新组件的state。\
// 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.
// 如果组件ref具有字符串引用,稍后将分配一个不同的对象
this.refs = emptyObject;
// We initialize the default updater but the real one gets injected by the
// renderer.
// 我们初始化默认的更新程序,但是真正的更新程序会被渲染
this.updater = updater || ReactNoopUpdateQueue;
}
Component.prototype.isReactComponent = {};
/**
*不能保证`this.state`会立即更新,因此
*调用此方法后访问`this.state`可能会返回旧值。
*
*不能保证对setState的调用将同步运行,
*因为它们最终可能会一起批处理。您可以提供可选
*实际调用setState时将执行的回调
*完成。
*
*将函数提供给setState时,它将在以下时间点被调用
*未来(不同步)。它将被称为最新
*组件参数(状态,道具,上下文)。这些值可以不同
*from this。*因为您的函数可能在receiveProps之后但之前被调用
*shouldComponentUpdate,这个新的状态,道具和上下文还没有
*分配给这个
*
* @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');
};
/**
强制更新。仅当已知时才应调用此方法
*确定我们不是DOM事务中的**。
*
*如果您知道
*组件的状态已更改,但未调用`setState`。
*
*这不会调用`shouldComponentUpdate`,但是会调用
*componentWillUpdate和componentDidUpdate。
*
* @param {?function} callback Called after update is complete.
* @final
* @protected
*/
Component.prototype.forceUpdate = function(callback) {
this.updater.enqueueForceUpdate(this, callback, 'forceUpdate');
};
/**
不推荐使用的API。这些API曾经存在于经典的React类上,但是由于
*我们要弃用它们,我们不会将它们移至此
*现代基层。取而代之的是,我们定义了一个getter,如果它被访问,它会发出警告
已经废弃
*/
if (__DEV__) {
const deprecatedAPIs = {
isMounted: [
'isMounted',
'Instead, make sure to clean up subscriptions and pending requests in ' +
'componentWillUnmount to prevent memory leaks.',
],
replaceState: [
'replaceState',
'Refactor your code to use setState instead (see ' +
'https://github.com/facebook/react/issues/3236).',
],
};
const defineDeprecationWarning = function(methodName, info) {
Object.defineProperty(Component.prototype, methodName, {
get: function() {
lowPriorityWarning(
false,
'%s(...) is deprecated in plain JavaScript React classes. %s',
info[0],
info[1],
);
return undefined;
},
});
};
for (const fnName in deprecatedAPIs) {
if (deprecatedAPIs.hasOwnProperty(fnName)) {
defineDeprecationWarning(fnName, deprecatedAPIs[fnName]);
}
}
}
//虚拟组件
function ComponentDummy() {}
ComponentDummy.prototype = Component.prototype;
// 带有默认浅层相等性检查的便利组件。
/**
* Convenience component with default shallow equality check for sCU.
*/
// PureComponent最佳情况是展示组件
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;
}
const pureComponentPrototype = (PureComponent.prototype = new ComponentDummy());
// PureComponent.prototype等于ComponentDummy的实例 只继承Component的原型,不包括constructor,以此来节省内存。
pureComponentPrototype.constructor = PureComponent;
// 原型的constructor等于自身,覆盖掉Component.prototype的constructor(Component)
// Avoid an extra prototype jump for these methods.
// 对于这些方法,请避免额外的原型跳转 为了减少一次原型链查找
Object.assign(pureComponentPrototype, Component.prototype);
pureComponentPrototype.isPureReactComponent = true;
// PureComponent是自带了一个简单的shouldComponentUpdate来优化更新机制的
export {Component, PureComponent};
https://juejin.im/post/5b614d...
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。