ReactBaseClasses
这个文件是export
出了Component
, PureComponent
react
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...