【React】版本18 代码遨游(七) ReactFiberClassComponent 组件挂载、更新

ReactFiberClassComponent.new

在创建Component组件的时候,我们需要传入Updater,控制组件状态的更新。今天我们来看看Updater的源码,定义,看能学习到什么东西。

位置:react-reconciler\src\ReactFiberClassComponent.new.js

classComponentUpdater

// Updater 作为一个对象
const classComponentUpdater = {
   
  // 属性是否挂载
  isMounted,
  // 入队设置状态state
  enqueueSetState(inst, payload, callback) {
   
    // 取得实例上的fiber
    const fiber = getInstance(inst);
    // 初始化事件时间
    const eventTime = requestEventTime();
    // 请求一条合适的车道
    const lane = requestUpdateLane(fiber);
    // 初始化一个update
    const update = createUpdate(eventTime, lane);
    // 完善update的负载和callback信息
    update.payload = payload;
    if (callback !== undefined && callback !== null) {
   
      if (__DEV__) {
   
        warnOnInvalidCallback(callback, 'setState');
      }
      update.callback = callback;
    }
    // 将update入队
    enqueueUpdate(fiber, update, lane);
    const root = scheduleUpdateOnFiber(fiber, lane, eventTime);
    if (root !== null) {
   
      entangleTransitions(root, fiber, lane);
    }

    if (__DEV__) {
   
      if (enableDebugTracing) {
   
        if (fiber.mode & DebugTracingMode) {
   
          const name = getComponentNameFromFiber(fiber) || 'Unknown';
          logStateUpdateScheduled(name, lane, payload);
        }
      }
    }

    if (enableSchedulingProfiler) {
   
      markStateUpdateScheduled(fiber, lane);
    }
  },
  // 替换状态state方法,大同小异,component文中已经看过了
  enqueueReplaceState(inst, payload, callback) {
   
    const fiber = getInstance(inst);
    const eventTime = requestEventTime();
    const lane = requestUpdateLane(fiber);

    const update = createUpdate(eventTime, lane);
    update.tag = ReplaceState;
    update.payload = payload;

    if (callback !== undefined && callback !== null) {
   
      if (__DEV__) {
   
        warnOnInvalidCallback(callback, 'replaceState');
      }
      update.callback = callback;
    }

    enqueueUpdate(fiber, update, lane);
    const root = scheduleUpdateOnFiber(fiber, lane, eventTime);
    if (root !== null) {
   
      entangleTransitions(root, fiber, lane);
    }

    if (__DEV__) {
   
      if (enableDebugTracing) {
   
        if (fiber.mode & DebugTracingMode) {
   
          const name = getComponentNameFromFiber(fiber) || 'Unknown';
          logStateUpdateScheduled(name, lane, payload);
        }
      }
    }

    if (enableSchedulingProfiler) {
   
      markStateUpdateScheduled(fiber, lane);
    }
  },
  // 强制更新方法,同样见component一文
  enqueueForceUpdate(inst, callback) {
   
    const fiber = getInstance(inst);
    const eventTime = requestEventTime();
    const lane = requestUpdateLane(fiber);

    const update = createUpdate(eventTime, lane);
    update.tag = ForceUpdate;

    if (callback !== undefined && callback !== null) {
   
      if (__DEV__) {
   
        warnOnInvalidCallback(callback, 'forceUpdate');
      }
      update.callback = callback;
    }

    enqueueUpdate(fiber, update, lane);
    const root = scheduleUpdateOnFiber(fiber, lane, eventTime);
    if (root !== null) {
   
      entangleTransitions(root, fiber, lane);
    }

    if (__DEV__) {
   
      if (enableDebugTracing) {
   
        if (fiber.mode & DebugTracingMode) {
   
          const name = getComponentNameFromFiber(fiber) || 'Unknown';
          logForceUpdateScheduled(name, lane);
        }
      }
    }

    if (enableSchedulingProfiler) {
   
      markForceUpdateScheduled(fiber, lane);
    }
  },
};

checkShouldComponentUpdate

检查组件是否应该更新

function checkShouldComponentUpdate(
  workInProgress,
  ctor,
  oldProps,
  newProps,
  oldState,
  newState,
  nextContext,
) {
   
  // 先取得当前fiber的本地状态实例 instance
  const instance = workInProgress.stateNode;
  // 如果状态中用户定义了 shouldComponentUpdate方法
  if (typeof instance.shouldComponentUpdate === 'function') {
   
    // 传入shouldComponentUpdate方法当前新的Props和新的状态,以及下一个上下文
    let shouldUpdate = instance.shouldComponentUpdate(
      newProps,
      newState,
      nextContext,
    );
    if (__DEV__) {
   
      if (
        debugRenderPhaseSideEffectsForStrictMode &&
        workInProgress.mode & StrictLegacyMode
      ) {
   
        disableLogs();
        try {
   
          // Invoke the function an extra time to help detect side-effects.
          shouldUpdate = instance.shouldComponentUpdate(
            newProps,
            newState,
            nextContext,
          );
        } finally {
   
          reenableLogs();
        }
      }
      // 没有定义shouldComponentUpdate方法,报错
      if (shouldUpdate === undefined) {
   
        console.error(
          '%s.shouldComponentUpdate(): Returned undefined instead of a ' +
            'boolean value. Make sure to return true or false.',
          getComponentNameFromType(ctor) || 'Component',
        );
      }
    }

    return shouldUpdate;
  }
  // 如果是pureComponent,浅比较Props和State
  if (ctor.prototype && ctor.prototype.isPureReactComponent) {
   
    return (
      !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState)
    );
  }
  // 以上都没有返回值,则默认返回true
  return true;
}

checkClassInstance

DEV模式下检查Fiber实例的定义

function checkClassInstance(workInProgress: Fiber, ctor: any, newProps: any) {
   
  // 获取fiber的状态实例
  const instance = workInProgress.stateNode;
  if (__DEV__) {
   
    // 组件名
    const name = getComponentNameFromType(ctor) || 'Component';
    // 组件的render方法
    const renderPresent = instance.render;

    // 检查render方法是否存在
    if (!renderPresent) {
   
      if (ctor.prototype && typeof ctor.prototype.render === 'function') {
   
        console.error(
          '%s(...): No `render` method found on the returned component ' +
            'instance: did you accidentally return an object from the constructor?',
          name,
        );
      } else {
   
        console.error(
          '%s(...): No `render` method found on the returned component ' +
            'instance: you may have forgotten to define `render`.',
          name,
        );
      }
    }
    // 如果实例上有getInitialState方法但是实例并不是React类
    if (
      instance.getInitialState &&
      !instance.getInitialState.isReactClassApproved &&
      !instance.state
    ) {
   
      console.error(
        'getInitialState was defined on %s, a plain JavaScript class. ' +
          'This is only supported for classes created using React.createClass. ' +
          'Did you mean to define a state property instead?',
        name,
      );
    }
    // 如果实例有getDefaultProps方法但是实例不是React类
    if (
      instance.getDefaultProps &&
      !instance.getDefaultProps.isReactClassApproved
    )
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值