美文网首页
packages/react/ReactBaseClasses.

packages/react/ReactBaseClasses.

作者: Ahungrynoob | 来源:发表于2019-08-01 12:38 被阅读0次

    这一篇是解析packages/react/ReactBaseClasses.js的源码的

    像文件名说的那样,这个文件主要定义了Component、PureComponent 这两个基础类;

    Component

    Component类主要实现了以下两个原型链的方法:setStateforceUpdate,这两个方法的背后是基于updater去实现的(如果没有正确实例化并被挂载时会用ReactNoopUpdateQueue去实现);
    ReactNoopUpdateQueue的处理行为就是针对enqueueSetStateenqueueForceUpdate去给出警告,告诉开发者,这里可能会有潜在的bug
    以下是他们的源代码:

    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');
    };
    
    Component.prototype.forceUpdate = function(callback) {
      this.updater.enqueueForceUpdate(this, callback, 'forceUpdate');
    };
    

    然后比较关键的处理行为:
    在开发模式下会针对两个deprecatedAPIs:isMountedreplaceState去做get时候的警告:

    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]);
        }
      }
    }
    

    PureComponent基类的实现

    PureComponent的实现是通过ComponentDummy这个中间类去实现的;
    ComponentDummy的作用就是断开对于Component.prototype的引用,这样在修改PureComponent的原型链方法的时候不会对Component造成影响,同时为了避免原型链的跳跃,做了一个Object.assign(pureComponentPrototype, Component.prototype);的处理。

    function ComponentDummy() {}
    ComponentDummy.prototype = Component.prototype;
    
    /**
     * Convenience component with default shallow equality check for sCU.
     */
    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());
    pureComponentPrototype.constructor = PureComponent;
    // Avoid an extra prototype jump for these methods.
    Object.assign(pureComponentPrototype, Component.prototype);
    pureComponentPrototype.isPureReactComponent = true;
    

    相关文章

      网友评论

          本文标题:packages/react/ReactBaseClasses.

          本文链接:https://www.haomeiwen.com/subject/atjqdctx.html