【04.30】React

82 阅读1分钟

render阶段

commit阶段

commitRootImpl

v18

源码地址

function commitRootImpl(
    root: FiberRoot,
    recoverableErrors: null | Array<mixed>,
    transitions: Array<Transition> | null,
    renderPriorityLevel: EventPriority,
  ) {
    // If there are pending passive effects, schedule a callback to process them.
    // Do this as early as possible, so it is queued before anything else that
    // might get scheduled in the commit phase. (See #16714.)
    // TODO: Delete all other places that schedule the passive effect callback
    // They're redundant.
    if (
        (finishedWork.subtreeFlags & PassiveMask) !== NoFlags ||
        (finishedWork.flags & PassiveMask) !== NoFlags
      ) {
        if (!rootDoesHavePassiveEffects) {
          rootDoesHavePassiveEffects = true;
          pendingPassiveEffectsRemainingLanes = remainingLanes;
          // workInProgressTransitions might be overwritten, so we want
          // to store it in pendingPassiveTransitions until they get processed
          // We need to pass this through as an argument to commitRoot
          // because workInProgressTransitions might have changed between
          // the previous render and commit if we throttle the commit
          // with setTimeout
          pendingPassiveTransitions = transitions;
          scheduleCallback(NormalSchedulerPriority, () => {
            flushPassiveEffects();
            // This render triggered passive effects: release the root cache pool
            // *after* passive effects fire to avoid freeing a cache pool that may
            // be referenced by a node in the tree (HostRoot, Cache boundary etc)
            return null;
          });
        }
      }
  
    return null;
  }

在v18中,commit阶段,会在before mutation之前处理useEffect(flushPassiveEffects)

v17

源码地址

function commitRootImpl(root, renderPriorityLevel) {

    const finishedWork = root.finishedWork;
    const lanes = root.finishedLanes;

    root.finishedWork = null;
    root.finishedLanes = NoLanes;

    invariant(
        finishedWork !== root.current,
        'Cannot commit the same tree as before. This error is likely caused by ' +
        'a bug in React. Please file an issue.',
    );

    commitBeforeMutationEffects(finishedWork);
    return null;
}

function commitBeforeMutationEffects(firstChild) {
    let fiber = firstChild;
    while (fiber !== null) {
        commitBeforeMutationEffectsImpl(fiber);
        fiber = fiber.sibling;
    }
}

function commitBeforeMutationEffectsImpl(fiber) {
    const current = fiber.alternate;
    const flags = fiber.flags;

    if ((flags & Passive) !== NoFlags) {
        // If there are passive effects, schedule a callback to flush at
        // the earliest opportunity.
        if (!rootDoesHavePassiveEffects) {
            rootDoesHavePassiveEffects = true;
            scheduleCallback(NormalSchedulerPriority, () => {
                flushPassiveEffects();
                return null;
            });
        }
    }
}

在v17中,是在before mutation 阶段处理的