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...