乐趣区

关于react.js:React-beginWork

beginWork

params

  1. current: mount 时:只有 rootFiber 和 rootWorkInProgrss 的 current !== null;其余 current = null
  2. workInProgress
  3. renderLanes

依据 tag 执行不同办法;

  1. mountIndeterminateComponent: 不确定是 function 还是 class
  2. updateFunctionComponent:

    • renderWithHooks
    • reconcileChildren
  3. updateClassComponent:

    • 代码如下
    // 没有实例对象
    if (instance === null) {
      // 有 current 对象
      if (current !== null) {
        current.alternate = null;
        workInProgress.alternate = null;
        workInProgress.flags |= Placement;
      }
      /**
       * 1. 创立实例对象,将 state 挂载到 memoizedState
       * 2. 执行 adoptClassInstance
       */
      constructClassInstance(workInProgress, Component, nextProps);
      /**
       * 1. initializeUpdateQueue: 初始化 fiber 的 updateQueue
       * 2. processUpdateQueue: 计算 state 值
       */
      mountClassInstance(workInProgress, Component, nextProps, renderLanes);
      shouldUpdate = true;
    } else if (current === null) {
      // 有实例对象,没有 current 对象
      // 重用 instace 值
      shouldUpdate = resumeMountClassInstance(
        workInProgress,
        Component,
        nextProps,
        renderLanes
      );
    } else {
      /**
       * 1. cloneUpdateQueue
       * 2. processUpdateQueue
       */
      shouldUpdate = updateClassInstance(
        current,
        workInProgress,
        Component,
        nextProps,
        renderLanes
      );
    }
    • reconcileChildren
  4. updateHostRoot: FiberRoot

    • cloneUpdateQueue
    • processUpdateQueue
    • reconcileChildren

代码

  1. initializeUpdateQueue

    function initializeUpdateQueue(fiber) {
      var queue = {
        baseState: fiber.memoizedState,
        firstBaseUpdate: null,
        lastBaseUpdate: null,
        shared: {pending: null,},
        effects: null,
      };
      fiber.updateQueue = queue;
    }
  2. processUpdateQueue

    • 计算 state 值
    • mount: 将 state 赋值到 workInProgress.memoizedState;将 updateQueue.baseState 赋值
    • update
    function processUpdateQueue(workInProgress, props, instance, renderLanes) {
      var queue = workInProgress.updateQueue;
      hasForceUpdate = false;
    
      {currentlyProcessingQueue = queue.shared;}
    
      var firstBaseUpdate = queue.firstBaseUpdate;
      var lastBaseUpdate = queue.lastBaseUpdate;
      var pendingQueue = queue.shared.pending;
    
      if (pendingQueue !== null) {
        queue.shared.pending = null;
    
        var lastPendingUpdate = pendingQueue;
        var firstPendingUpdate = lastPendingUpdate.next;
        lastPendingUpdate.next = null;
    
        if (lastBaseUpdate === null) {firstBaseUpdate = firstPendingUpdate;} else {lastBaseUpdate.next = firstPendingUpdate;}
    
        lastBaseUpdate = lastPendingUpdate;
    
        var current = workInProgress.alternate;
    
        if (current !== null) {
          var currentQueue = current.updateQueue;
          var currentLastBaseUpdate = currentQueue.lastBaseUpdate;
    
          if (currentLastBaseUpdate !== lastBaseUpdate) {if (currentLastBaseUpdate === null) {currentQueue.firstBaseUpdate = firstPendingUpdate;} else {currentLastBaseUpdate.next = firstPendingUpdate;}
    
            currentQueue.lastBaseUpdate = lastPendingUpdate;
          }
        }
      }
    
      if (firstBaseUpdate !== null) {
        var newState = queue.baseState;
    
        var newLanes = NoLanes;
        var newBaseState = null;
        var newFirstBaseUpdate = null;
        var newLastBaseUpdate = null;
        var update = firstBaseUpdate;
    
        do {
          var updateLane = update.lane;
          var updateEventTime = update.eventTime;
    
          if (!isSubsetOfLanes(renderLanes, updateLane)) {
            var clone = {
              eventTime: updateEventTime,
              lane: updateLane,
              tag: update.tag,
              payload: update.payload,
              callback: update.callback,
              next: null,
            };
    
            if (newLastBaseUpdate === null) {
              newFirstBaseUpdate = newLastBaseUpdate = clone;
              newBaseState = newState;
            } else {newLastBaseUpdate = newLastBaseUpdate.next = clone;}
    
            newLanes = mergeLanes(newLanes, updateLane);
          } else {if (newLastBaseUpdate !== null) {
              var _clone = {
                eventTime: updateEventTime,
                lane: NoLane,
                tag: update.tag,
                payload: update.payload,
                callback: update.callback,
                next: null,
              };
              newLastBaseUpdate = newLastBaseUpdate.next = _clone;
            }
    
            newState = getStateFromUpdate(
              workInProgress,
              queue,
              update,
              newState,
              props,
              instance
            );
            var callback = update.callback;
    
            if (callback !== null) {
              workInProgress.flags |= Callback;
              var effects = queue.effects;
    
              if (effects === null) {queue.effects = [update];
              } else {effects.push(update);
              }
            }
          }
    
          update = update.next;
    
          if (update === null) {
            pendingQueue = queue.shared.pending;
    
            if (pendingQueue === null) {break;} else {
              var _lastPendingUpdate = pendingQueue;
    
              var _firstPendingUpdate = _lastPendingUpdate.next;
              _lastPendingUpdate.next = null;
              update = _firstPendingUpdate;
              queue.lastBaseUpdate = _lastPendingUpdate;
              queue.shared.pending = null;
            }
          }
        } while (true);
    
        if (newLastBaseUpdate === null) {newBaseState = newState;}
    
        queue.baseState = newBaseState;
        queue.firstBaseUpdate = newFirstBaseUpdate;
        queue.lastBaseUpdate = newLastBaseUpdate;
    
        markSkippedUpdateLanes(newLanes);
        workInProgress.lanes = newLanes;
        workInProgress.memoizedState = newState;
      }
    
      {currentlyProcessingQueue = null;}
    }
  3. adoptClassInstance

    • instance.update: this.setState 应用
    • workInProgress.stateNode = instance;
    function adoptClassInstance(workInProgress, instance) {
      instance.updater = classComponentUpdater;
      workInProgress.stateNode = instance;
    
      set(instance, workInProgress);
    
      {instance._reactInternalInstance = fakeInternalInstance;}
    }
  4. classComponentUpdater 对象

    var classComponentUpdater = {
      isMounted: isMounted,
      enqueueSetState: function (inst, payload, callback) {var fiber = get(inst);
        var eventTime = requestEventTime();
        var lane = requestUpdateLane(fiber);
        var update = createUpdate(eventTime, lane);
        update.payload = payload;
    
        if (callback !== undefined && callback !== null) {
          {warnOnInvalidCallback(callback, "setState");
          }
    
          update.callback = callback;
        }
    
        enqueueUpdate(fiber, update);
        scheduleUpdateOnFiber(fiber, lane, eventTime);
      },
      enqueueReplaceState: function (inst, payload, callback) {var fiber = get(inst);
        var eventTime = requestEventTime();
        var lane = requestUpdateLane(fiber);
        var update = createUpdate(eventTime, lane);
        update.tag = ReplaceState;
        update.payload = payload;
    
        if (callback !== undefined && callback !== null) {
          {warnOnInvalidCallback(callback, "replaceState");
          }
    
          update.callback = callback;
        }
    
        enqueueUpdate(fiber, update);
        scheduleUpdateOnFiber(fiber, lane, eventTime);
      },
      enqueueForceUpdate: function (inst, callback) {var fiber = get(inst);
        var eventTime = requestEventTime();
        var lane = requestUpdateLane(fiber);
        var update = createUpdate(eventTime, lane);
        update.tag = ForceUpdate;
    
        if (callback !== undefined && callback !== null) {
          {warnOnInvalidCallback(callback, "forceUpdate");
          }
    
          update.callback = callback;
        }
    
        enqueueUpdate(fiber, update);
        scheduleUpdateOnFiber(fiber, lane, eventTime);
      },
    };
  5. renderWithHooks

    • currentlyRenderingFiber$1 = workInProgress;
    • 执行函数组件: Component(props, secondArg);函数组件中的 hooks 也会执行;将 hooks 挂载到 Fiber.memoizedState
    function mountWorkInProgressHook() {
      var hook = {
        memoizedState: null,
        baseState: null,
        baseQueue: null,
        queue: null,
        next: null,
      };
    
      if (workInProgressHook === null) {currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook;} else {workInProgressHook = workInProgressHook.next = hook;}
    
      return workInProgressHook;
    }
退出移动版