Best JavaScript code snippet using playwright-internal
ReactFiberWorkLoop.old.js
Source:ReactFiberWorkLoop.old.js  
...179    return findRetryLane(currentEventWipLanes);180  }181  function scheduleUpdateOnFiber(fiber, lane, eventTime) {182    checkForNestedUpdates();183    warnAboutRenderPhaseUpdatesInDEV(fiber);184    var root = markUpdateLaneFromFiberToRoot(fiber, lane);185    if (root === null) {186      warnAboutUpdateOnUnmountedFiberInDEV(fiber);187      return null;188    } // Mark that the root has a pending update.189    markRootUpdated(root, lane, eventTime);190    if (root === workInProgressRoot) {191      // Received an update to a tree that's in the middle of rendering. Mark192      // that there was an interleaved update work on this root. Unless the193      // `deferRenderPhaseUpdateToNextBatch` flag is off and this is a render194      // phase update. In that case, we don't treat render phase updates as if195      // they were interleaved, for backwards compat reasons.196      {197        workInProgressRootUpdatedLanes = mergeLanes(workInProgressRootUpdatedLanes, lane);198      }199      if (workInProgressRootExitStatus === RootSuspendedWithDelay) {200        // The root already suspended with a delay, which means this render201        // definitely won't finish. Since we have a new update, let's mark it as202        // suspended now, right before marking the incoming update. This has the203        // effect of interrupting the current render and switching to the update.204        // TODO: Make sure this doesn't override pings that happen while we've205        // already started rendering.206        markRootSuspended$1(root, workInProgressRootRenderLanes);207      }208    } // TODO: requestUpdateLanePriority also reads the priority. Pass the209    // priority as an argument to that function and this one.210    var priorityLevel = getCurrentPriorityLevel();211    if (lane === SyncLane) {212      if ( // Check if we're inside unbatchedUpdates213      (executionContext & LegacyUnbatchedContext) !== NoContext && // Check if we're not already rendering214      (executionContext & (RenderContext | CommitContext)) === NoContext) {215        // Register pending interactions on the root to avoid losing traced interaction data.216        schedulePendingInteractions(root, lane); // This is a legacy edge case. The initial mount of a ReactDOM.render-ed217        // root inside of batchedUpdates should be synchronous, but layout updates218        // should be deferred until the end of the batch.219        performSyncWorkOnRoot(root);220      } else {221        ensureRootIsScheduled(root, eventTime);222        schedulePendingInteractions(root, lane);223        if (executionContext === NoContext) {224          // Flush the synchronous work now, unless we're already working or inside225          // a batch. This is intentionally inside scheduleUpdateOnFiber instead of226          // scheduleCallbackForFiber to preserve the ability to schedule a callback227          // without immediately flushing it. We only do this for user-initiated228          // updates, to preserve historical behavior of legacy mode.229          resetRenderTimer();230          flushSyncCallbackQueue();231        }232      }233    } else {234      // Schedule a discrete update but only if it's not Sync.235      if ((executionContext & DiscreteEventContext) !== NoContext && ( // Only updates at user-blocking priority or greater are considered236      // discrete, even inside a discrete event.237      priorityLevel === UserBlockingPriority$2 || priorityLevel === ImmediatePriority$1)) {238        // This is the result of a discrete event. Track the lowest priority239        // discrete update per root so we can flush them early, if needed.240        if (rootsWithPendingDiscreteUpdates === null) {241          rootsWithPendingDiscreteUpdates = new Set([root]);242        } else {243          rootsWithPendingDiscreteUpdates.add(root);244        }245      } // Schedule other updates after in case the callback is sync.246      ensureRootIsScheduled(root, eventTime);247      schedulePendingInteractions(root, lane);248    } // We use this when assigning a lane for a transition inside249    // `requestUpdateLane`. We assume it's the same as the root being updated,250    // since in the common case of a single root app it probably is. If it's not251    // the same root, then it's not a huge deal, we just might batch more stuff252    // together more than necessary.253    mostRecentlyUpdatedRoot = root;254  } // This is split into a separate function so we can mark a fiber with pending255  // work without treating it as a typical update that originates from an event;256  // e.g. retrying a Suspense boundary isn't an update, but it does schedule work257  // on a fiber.258  function markUpdateLaneFromFiberToRoot(sourceFiber, lane) {259    // Update the source fiber's lanes260    sourceFiber.lanes = mergeLanes(sourceFiber.lanes, lane);261    var alternate = sourceFiber.alternate;262    if (alternate !== null) {263      alternate.lanes = mergeLanes(alternate.lanes, lane);264    }265    {266      if (alternate === null && (sourceFiber.flags & (Placement | Hydrating)) !== NoFlags) {267        warnAboutUpdateOnNotYetMountedFiberInDEV(sourceFiber);268      }269    } // Walk the parent path to the root and update the child expiration time.270    var node = sourceFiber;271    var parent = sourceFiber.return;272    while (parent !== null) {273      parent.childLanes = mergeLanes(parent.childLanes, lane);274      alternate = parent.alternate;275      if (alternate !== null) {276        alternate.childLanes = mergeLanes(alternate.childLanes, lane);277      } else {278        {279          if ((parent.flags & (Placement | Hydrating)) !== NoFlags) {280            warnAboutUpdateOnNotYetMountedFiberInDEV(sourceFiber);281          }282        }283      }284      node = parent;285      parent = parent.return;286    }287    if (node.tag === HostRoot) {288      var root = node.stateNode;289      return root;290    } else {291      return null;292    }293  } // Use this function to schedule a task for a root. There's only one task per294  // root; if a task was already scheduled, we'll check to make sure the priority295  // of the existing task is the same as the priority of the next level that the296  // root has work on. This function is called on every update, and right before297  // exiting a task.298  function ensureRootIsScheduled(root, currentTime) {299    var existingCallbackNode = root.callbackNode; // Check if any lanes are being starved by other work. If so, mark them as300    // expired so we know to work on those next.301    markStarvedLanesAsExpired(root, currentTime); // Determine the next lanes to work on, and their priority.302    var nextLanes = getNextLanes(root, root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes); // This returns the priority level computed during the `getNextLanes` call.303    var newCallbackPriority = returnNextLanesPriority();304    if (nextLanes === NoLanes) {305      // Special case: There's nothing to work on.306      if (existingCallbackNode !== null) {307        cancelCallback(existingCallbackNode);308        root.callbackNode = null;309        root.callbackPriority = NoLanePriority;310      }311      return;312    } // Check if there's an existing task. We may be able to reuse it.313    if (existingCallbackNode !== null) {314      var existingCallbackPriority = root.callbackPriority;315      if (existingCallbackPriority === newCallbackPriority) {316        // The priority hasn't changed. We can reuse the existing task. Exit.317        return;318      } // The priority changed. Cancel the existing callback. We'll schedule a new319      // one below.320      cancelCallback(existingCallbackNode);321    } // Schedule a new callback.322    var newCallbackNode;323    if (newCallbackPriority === SyncLanePriority) {324      // Special case: Sync React callbacks are scheduled on a special325      // internal queue326      newCallbackNode = scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root));327    } else if (newCallbackPriority === SyncBatchedLanePriority) {328      newCallbackNode = scheduleCallback(ImmediatePriority$1, performSyncWorkOnRoot.bind(null, root));329    } else {330      var schedulerPriorityLevel = lanePriorityToSchedulerPriority(newCallbackPriority);331      newCallbackNode = scheduleCallback(schedulerPriorityLevel, performConcurrentWorkOnRoot.bind(null, root));332    }333    root.callbackPriority = newCallbackPriority;334    root.callbackNode = newCallbackNode;335  } // This is the entry point for every concurrent task, i.e. anything that336  // goes through Scheduler.337  function performConcurrentWorkOnRoot(root) {338    // Since we know we're in a React event, we can clear the current339    // event time. The next update will compute a new event time.340    currentEventTime = NoTimestamp;341    currentEventWipLanes = NoLanes;342    currentEventPendingLanes = NoLanes;343    if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {344      {345        throw Error( "Should not already be working." );346      }347    } // Flush any pending passive effects before deciding which lanes to work on,348    // in case they schedule additional work.349    var originalCallbackNode = root.callbackNode;350    var didFlushPassiveEffects = flushPassiveEffects();351    if (didFlushPassiveEffects) {352      // Something in the passive effect phase may have canceled the current task.353      // Check if the task node for this root was changed.354      if (root.callbackNode !== originalCallbackNode) {355        // The current task was canceled. Exit. We don't need to call356        // `ensureRootIsScheduled` because the check above implies either that357        // there's a new task, or that there's no remaining work on this root.358        return null;359      }360    } // Determine the next expiration time to work on, using the fields stored361    // on the root.362    var lanes = getNextLanes(root, root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes);363    if (lanes === NoLanes) {364      // Defensive coding. This is never expected to happen.365      return null;366    }367    var exitStatus = renderRootConcurrent(root, lanes);368    if (includesSomeLane(workInProgressRootIncludedLanes, workInProgressRootUpdatedLanes)) {369      // The render included lanes that were updated during the render phase.370      // For example, when unhiding a hidden tree, we include all the lanes371      // that were previously skipped when the tree was hidden. That set of372      // lanes is a superset of the lanes we started rendering with.373      //374      // So we'll throw out the current work and restart.375      prepareFreshStack(root, NoLanes);376    } else if (exitStatus !== RootIncomplete) {377      if (exitStatus === RootErrored) {378        executionContext |= RetryAfterError; // If an error occurred during hydration,379        // discard server response and fall back to client side render.380        if (root.hydrate) {381          root.hydrate = false;382          clearContainer(root.containerInfo);383        } // If something threw an error, try rendering one more time. We'll render384        // synchronously to block concurrent data mutations, and we'll includes385        // all pending updates are included. If it still fails after the second386        // attempt, we'll give up and commit the resulting tree.387        lanes = getLanesToRetrySynchronouslyOnError(root);388        if (lanes !== NoLanes) {389          exitStatus = renderRootSync(root, lanes);390        }391      }392      if (exitStatus === RootFatalErrored) {393        var fatalError = workInProgressRootFatalError;394        prepareFreshStack(root, NoLanes);395        markRootSuspended$1(root, lanes);396        ensureRootIsScheduled(root, now());397        throw fatalError;398      } // We now have a consistent tree. The next step is either to commit it,399      // or, if something suspended, wait to commit it after a timeout.400      var finishedWork = root.current.alternate;401      root.finishedWork = finishedWork;402      root.finishedLanes = lanes;403      finishConcurrentRender(root, exitStatus, lanes);404    }405    ensureRootIsScheduled(root, now());406    if (root.callbackNode === originalCallbackNode) {407      // The task node scheduled for this root is the same one that's408      // currently executed. Need to return a continuation.409      return performConcurrentWorkOnRoot.bind(null, root);410    }411    return null;412  }413  function finishConcurrentRender(root, exitStatus, lanes) {414    switch (exitStatus) {415      case RootIncomplete:416      case RootFatalErrored:417        {418          {419            {420              throw Error( "Root did not complete. This is a bug in React." );421            }422          }423        }424      // Flow knows about invariant, so it complains if I add a break425      // statement, but eslint doesn't know about invariant, so it complains426      // if I do. eslint-disable-next-line no-fallthrough427      case RootErrored:428        {429          // We should have already attempted to retry this tree. If we reached430          // this point, it errored again. Commit it.431          commitRoot(root);432          break;433        }434      case RootSuspended:435        {436          markRootSuspended$1(root, lanes); // We have an acceptable loading state. We need to figure out if we437          // should immediately commit it or wait a bit.438          if (includesOnlyRetries(lanes) && // do not delay if we're inside an act() scope439          !shouldForceFlushFallbacksInDEV()) {440            // This render only included retries, no updates. Throttle committing441            // retries so that we don't show too many loading states too quickly.442            var msUntilTimeout = globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now(); // Don't bother with a very short suspense time.443            if (msUntilTimeout > 10) {444              var nextLanes = getNextLanes(root, NoLanes);445              if (nextLanes !== NoLanes) {446                // There's additional work on this root.447                break;448              }449              var suspendedLanes = root.suspendedLanes;450              if (!isSubsetOfLanes(suspendedLanes, lanes)) {451                // We should prefer to render the fallback of at the last452                // suspended level. Ping the last suspended level to try453                // rendering it again.454                // FIXME: What if the suspended lanes are Idle? Should not restart.455                var eventTime = requestEventTime();456                markRootPinged(root, suspendedLanes);457                break;458              } // The render is suspended, it hasn't timed out, and there's no459              // lower priority work to do. Instead of committing the fallback460              // immediately, wait for more data to arrive.461              root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), msUntilTimeout);462              break;463            }464          } // The work expired. Commit immediately.465          commitRoot(root);466          break;467        }468      case RootSuspendedWithDelay:469        {470          markRootSuspended$1(root, lanes);471          if (includesOnlyTransitions(lanes)) {472            // This is a transition, so we should exit without committing a473            // placeholder and without scheduling a timeout. Delay indefinitely474            // until we receive more data.475            break;476          }477          if (!shouldForceFlushFallbacksInDEV()) {478            // This is not a transition, but we did trigger an avoided state.479            // Schedule a placeholder to display after a short delay, using the Just480            // Noticeable Difference.481            // TODO: Is the JND optimization worth the added complexity? If this is482            // the only reason we track the event time, then probably not.483            // Consider removing.484            var mostRecentEventTime = getMostRecentEventTime(root, lanes);485            var eventTimeMs = mostRecentEventTime;486            var timeElapsedMs = now() - eventTimeMs;487            var _msUntilTimeout = jnd(timeElapsedMs) - timeElapsedMs; // Don't bother with a very short suspense time.488            if (_msUntilTimeout > 10) {489              // Instead of committing the fallback immediately, wait for more data490              // to arrive.491              root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), _msUntilTimeout);492              break;493            }494          } // Commit the placeholder.495          commitRoot(root);496          break;497        }498      case RootCompleted:499        {500          // The work completed. Ready to commit.501          commitRoot(root);502          break;503        }504      default:505        {506          {507            {508              throw Error( "Unknown root exit status." );509            }510          }511        }512    }513  }514  function markRootSuspended$1(root, suspendedLanes) {515    // When suspending, we should always exclude lanes that were pinged or (more516    // rarely, since we try to avoid it) updated during the render phase.517    // TODO: Lol maybe there's a better way to factor this besides this518    // obnoxiously named function :)519    suspendedLanes = removeLanes(suspendedLanes, workInProgressRootPingedLanes);520    suspendedLanes = removeLanes(suspendedLanes, workInProgressRootUpdatedLanes);521    markRootSuspended(root, suspendedLanes);522  } // This is the entry point for synchronous tasks that don't go523  // through Scheduler524  function performSyncWorkOnRoot(root) {525    if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {526      {527        throw Error( "Should not already be working." );528      }529    }530    flushPassiveEffects();531    var lanes;532    var exitStatus;533    if (root === workInProgressRoot && includesSomeLane(root.expiredLanes, workInProgressRootRenderLanes)) {534      // There's a partial tree, and at least one of its lanes has expired. Finish535      // rendering it before rendering the rest of the expired work.536      lanes = workInProgressRootRenderLanes;537      exitStatus = renderRootSync(root, lanes);538      if (includesSomeLane(workInProgressRootIncludedLanes, workInProgressRootUpdatedLanes)) {539        // The render included lanes that were updated during the render phase.540        // For example, when unhiding a hidden tree, we include all the lanes541        // that were previously skipped when the tree was hidden. That set of542        // lanes is a superset of the lanes we started rendering with.543        //544        // Note that this only happens when part of the tree is rendered545        // concurrently. If the whole tree is rendered synchronously, then there546        // are no interleaved events.547        lanes = getNextLanes(root, lanes);548        exitStatus = renderRootSync(root, lanes);549      }550    } else {551      lanes = getNextLanes(root, NoLanes);552      exitStatus = renderRootSync(root, lanes);553    }554    if (root.tag !== LegacyRoot && exitStatus === RootErrored) {555      executionContext |= RetryAfterError; // If an error occurred during hydration,556      // discard server response and fall back to client side render.557      if (root.hydrate) {558        root.hydrate = false;559        clearContainer(root.containerInfo);560      } // If something threw an error, try rendering one more time. We'll render561      // synchronously to block concurrent data mutations, and we'll includes562      // all pending updates are included. If it still fails after the second563      // attempt, we'll give up and commit the resulting tree.564      lanes = getLanesToRetrySynchronouslyOnError(root);565      if (lanes !== NoLanes) {566        exitStatus = renderRootSync(root, lanes);567      }568    }569    if (exitStatus === RootFatalErrored) {570      var fatalError = workInProgressRootFatalError;571      prepareFreshStack(root, NoLanes);572      markRootSuspended$1(root, lanes);573      ensureRootIsScheduled(root, now());574      throw fatalError;575    } // We now have a consistent tree. Because this is a sync render, we576    // will commit it even if something suspended.577    var finishedWork = root.current.alternate;578    root.finishedWork = finishedWork;579    root.finishedLanes = lanes;580    commitRoot(root); // Before exiting, make sure there's a callback scheduled for the next581    // pending level.582    ensureRootIsScheduled(root, now());583    return null;584  }585  function flushRoot(root, lanes) {586    markRootExpired(root, lanes);587    ensureRootIsScheduled(root, now());588    if ((executionContext & (RenderContext | CommitContext)) === NoContext) {589      resetRenderTimer();590      flushSyncCallbackQueue();591    }592  }593  function getExecutionContext() {594    return executionContext;595  }596  // flush reactäºä»¶597  function flushDiscreteUpdates() {598    // TODO: Should be able to flush inside batchedUpdates, but not inside `act`.599    // However, `act` uses `batchedUpdates`, so there's no way to distinguish600    // those two cases. Need to fix this before exposing flushDiscreteUpdates601    // as a public API.602    if ((executionContext & (BatchedContext | RenderContext | CommitContext)) !== NoContext) {603      {604        if ((executionContext & RenderContext) !== NoContext) {605          error('unstable_flushDiscreteUpdates: Cannot flush updates when React is ' + 'already rendering.');606        }607      } // We're already rendering, so we can't synchronously flush pending work.608      // This is probably a nested event dispatch triggered by a lifecycle/effect,609      // like `el.focus()`. Exit.610      return;611    }612    flushPendingDiscreteUpdates(); // If the discrete updates scheduled passive effects, flush them now so that613    // they fire before the next serial event.614    flushPassiveEffects();615  }616  function flushPendingDiscreteUpdates() {617    if (rootsWithPendingDiscreteUpdates !== null) {618      // For each root with pending discrete updates, schedule a callback to619      // immediately flush them.620      var roots = rootsWithPendingDiscreteUpdates;621      rootsWithPendingDiscreteUpdates = null;622      roots.forEach(function (root) {623        markDiscreteUpdatesExpired(root);624        ensureRootIsScheduled(root, now());625      });626    } // Now flush the immediate queue.627    flushSyncCallbackQueue();628  }629  function batchedUpdates$1(fn, a) {630    var prevExecutionContext = executionContext;631    executionContext |= BatchedContext;632    try {633      return fn(a);634    } finally {635      executionContext = prevExecutionContext;636      if (executionContext === NoContext) {637        // Flush the immediate callbacks that were scheduled during this batch638        resetRenderTimer();639        flushSyncCallbackQueue();640      }641    }642  }643  function batchedEventUpdates$1(fn, a) {644    var prevExecutionContext = executionContext;645    executionContext |= EventContext;646    try {647      return fn(a);648    } finally {649      executionContext = prevExecutionContext;650      if (executionContext === NoContext) {651        // Flush the immediate callbacks that were scheduled during this batch652        resetRenderTimer();653        flushSyncCallbackQueue();654      }655    }656  }657  function discreteUpdates$1(fn, a, b, c, d) {658    var prevExecutionContext = executionContext;659    executionContext |= DiscreteEventContext;660    {661      try {662        return runWithPriority$1(UserBlockingPriority$2, fn.bind(null, a, b, c, d));663      } finally {664        executionContext = prevExecutionContext;665        if (executionContext === NoContext) {666          // Flush the immediate callbacks that were scheduled during this batch667          resetRenderTimer();668          flushSyncCallbackQueue();669        }670      }671    }672  }673  // 鿹鿴æ°674  function unbatchedUpdates(fn, a) {675    var prevExecutionContext = executionContext;676    executionContext &= ~BatchedContext;677    executionContext |= LegacyUnbatchedContext;678    try {679      return fn(a);680    } finally {681      executionContext = prevExecutionContext;682      if (executionContext === NoContext) {683        // Flush the immediate callbacks that were scheduled during this batch684        resetRenderTimer();685        flushSyncCallbackQueue();686      }687    }688  }689  function flushSync(fn, a) {690    var prevExecutionContext = executionContext;691    if ((prevExecutionContext & (RenderContext | CommitContext)) !== NoContext) {692      {693        error('flushSync was called from inside a lifecycle method. React cannot ' + 'flush when React is already rendering. Consider moving this call to ' + 'a scheduler task or micro task.');694      }695      return fn(a);696    }697    executionContext |= BatchedContext;698    {699      try {700        if (fn) {701          return runWithPriority$1(ImmediatePriority$1, fn.bind(null, a));702        } else {703          return undefined;704        }705      } finally {706        executionContext = prevExecutionContext; // Flush the immediate callbacks that were scheduled during this batch.707        // Note that this will happen even if batchedUpdates is higher up708        // the stack.709        flushSyncCallbackQueue();710      }711    }712  }713  function flushControlled(fn) {714    var prevExecutionContext = executionContext;715    executionContext |= BatchedContext;716    {717      try {718        runWithPriority$1(ImmediatePriority$1, fn);719      } finally {720        executionContext = prevExecutionContext;721        if (executionContext === NoContext) {722          // Flush the immediate callbacks that were scheduled during this batch723          resetRenderTimer();724          flushSyncCallbackQueue();725        }726      }727    }728  }729  function pushRenderLanes(fiber, lanes) {730    push(subtreeRenderLanesCursor, subtreeRenderLanes, fiber);731    subtreeRenderLanes = mergeLanes(subtreeRenderLanes, lanes);732    workInProgressRootIncludedLanes = mergeLanes(workInProgressRootIncludedLanes, lanes);733  }734  function popRenderLanes(fiber) {735    subtreeRenderLanes = subtreeRenderLanesCursor.current;736    pop(subtreeRenderLanesCursor, fiber);737  }738  function prepareFreshStack(root, lanes) {739    root.finishedWork = null;740    root.finishedLanes = NoLanes;741    var timeoutHandle = root.timeoutHandle;742    if (timeoutHandle !== noTimeout) {743      // The root previous suspended and scheduled a timeout to commit a fallback744      // state. Now that we have additional work, cancel the timeout.745      root.timeoutHandle = noTimeout; // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above746      cancelTimeout(timeoutHandle);747    }748    if (workInProgress !== null) {749      var interruptedWork = workInProgress.return;750      while (interruptedWork !== null) {751        unwindInterruptedWork(interruptedWork);752        interruptedWork = interruptedWork.return;753      }754    }755    workInProgressRoot = root;756    workInProgress = createWorkInProgress(root.current, null);757    workInProgressRootRenderLanes = subtreeRenderLanes = workInProgressRootIncludedLanes = lanes;758    workInProgressRootExitStatus = RootIncomplete;759    workInProgressRootFatalError = null;760    workInProgressRootSkippedLanes = NoLanes;761    workInProgressRootUpdatedLanes = NoLanes;762    workInProgressRootPingedLanes = NoLanes;763    {764      spawnedWorkDuringRender = null;765    }766    {767      ReactStrictModeWarnings.discardPendingWarnings();768    }769  }770  function handleError(root, thrownValue) {771    do {772      var erroredWork = workInProgress;773      try {774        // Reset module-level state that was set during the render phase.775        resetContextDependencies();776        resetHooksAfterThrow();777        resetCurrentFiber(); // TODO: I found and added this missing line while investigating a778        // separate issue. Write a regression test using string refs.779        ReactCurrentOwner$2.current = null;780        if (erroredWork === null || erroredWork.return === null) {781          // Expected to be working on a non-root fiber. This is a fatal error782          // because there's no ancestor that can handle it; the root is783          // supposed to capture all errors that weren't caught by an error784          // boundary.785          workInProgressRootExitStatus = RootFatalErrored;786          workInProgressRootFatalError = thrownValue; // Set `workInProgress` to null. This represents advancing to the next787          // sibling, or the parent if there are no siblings. But since the root788          // has no siblings nor a parent, we set it to null. Usually this is789          // handled by `completeUnitOfWork` or `unwindWork`, but since we're790          // intentionally not calling those, we need set it here.791          // TODO: Consider calling `unwindWork` to pop the contexts.792          workInProgress = null;793          return;794        }795        if (enableProfilerTimer && erroredWork.mode & ProfileMode) {796          // Record the time spent rendering before an error was thrown. This797          // avoids inaccurate Profiler durations in the case of a798          // suspended render.799          stopProfilerTimerIfRunningAndRecordDelta(erroredWork, true);800        }801        throwException(root, erroredWork.return, erroredWork, thrownValue, workInProgressRootRenderLanes);802        completeUnitOfWork(erroredWork);803      } catch (yetAnotherThrownValue) {804        // Something in the return path also threw.805        thrownValue = yetAnotherThrownValue;806        if (workInProgress === erroredWork && erroredWork !== null) {807          // If this boundary has already errored, then we had trouble processing808          // the error. Bubble it to the next boundary.809          erroredWork = erroredWork.return;810          workInProgress = erroredWork;811        } else {812          erroredWork = workInProgress;813        }814        continue;815      } // Return to the normal work loop.816      return;817    } while (true);818  }819  function pushDispatcher() {820    var prevDispatcher = ReactCurrentDispatcher$2.current;821    ReactCurrentDispatcher$2.current = ContextOnlyDispatcher;822    if (prevDispatcher === null) {823      // The React isomorphic package does not include a default dispatcher.824      // Instead the first renderer will lazily attach one, in order to give825      // nicer error messages.826      return ContextOnlyDispatcher;827    } else {828      return prevDispatcher;829    }830  }831  function popDispatcher(prevDispatcher) {832    ReactCurrentDispatcher$2.current = prevDispatcher;833  }834  function pushInteractions(root) {835    {836      var prevInteractions = __interactionsRef.current;837      __interactionsRef.current = root.memoizedInteractions;838      return prevInteractions;839    }840  }841  function popInteractions(prevInteractions) {842    {843      __interactionsRef.current = prevInteractions;844    }845  }846  function markCommitTimeOfFallback() {847    globalMostRecentFallbackTime = now();848  }849  function markSkippedUpdateLanes(lane) {850    workInProgressRootSkippedLanes = mergeLanes(lane, workInProgressRootSkippedLanes);851  }852  function renderDidSuspend() {853    if (workInProgressRootExitStatus === RootIncomplete) {854      workInProgressRootExitStatus = RootSuspended;855    }856  }857  function renderDidSuspendDelayIfPossible() {858    if (workInProgressRootExitStatus === RootIncomplete || workInProgressRootExitStatus === RootSuspended) {859      workInProgressRootExitStatus = RootSuspendedWithDelay;860    } // Check if there are updates that we skipped tree that might have unblocked861    // this render.862    if (workInProgressRoot !== null && (includesNonIdleWork(workInProgressRootSkippedLanes) || includesNonIdleWork(workInProgressRootUpdatedLanes))) {863      // Mark the current render as suspended so that we switch to working on864      // the updates that were skipped. Usually we only suspend at the end of865      // the render phase.866      // TODO: We should probably always mark the root as suspended immediately867      // (inside this function), since by suspending at the end of the render868      // phase introduces a potential mistake where we suspend lanes that were869      // pinged or updated while we were rendering.870      markRootSuspended$1(workInProgressRoot, workInProgressRootRenderLanes);871    }872  }873  function renderDidError() {874    if (workInProgressRootExitStatus !== RootCompleted) {875      workInProgressRootExitStatus = RootErrored;876    }877  } // Called during render to determine if anything has suspended.878  // Returns false if we're not sure.879  function renderHasNotSuspendedYet() {880    // If something errored or completed, we can't really be sure,881    // so those are false.882    return workInProgressRootExitStatus === RootIncomplete;883  }884  function renderRootSync(root, lanes) {885    var prevExecutionContext = executionContext;886    executionContext |= RenderContext;887    var prevDispatcher = pushDispatcher(); // If the root or lanes have changed, throw out the existing stack888    // and prepare a fresh one. Otherwise we'll continue where we left off.889    if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) {890      prepareFreshStack(root, lanes);891      startWorkOnPendingInteractions(root, lanes);892    }893    var prevInteractions = pushInteractions(root);894    {895      markRenderStarted(lanes);896    }897    do {898      try {899        workLoopSync();900        break;901      } catch (thrownValue) {902        handleError(root, thrownValue);903      }904    } while (true);905    resetContextDependencies();906    {907      popInteractions(prevInteractions);908    }909    executionContext = prevExecutionContext;910    popDispatcher(prevDispatcher);911    if (workInProgress !== null) {912      // This is a sync render, so we should have finished the whole tree.913      {914        {915          throw Error( "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." );916        }917      }918    }919    {920      markRenderStopped();921    } // Set this to null to indicate there's no in-progress render.922    workInProgressRoot = null;923    workInProgressRootRenderLanes = NoLanes;924    return workInProgressRootExitStatus;925  } // The work loop is an extremely hot path. Tell Closure not to inline it.926  /** @noinline */927  function workLoopSync() {928    // Already timed out, so perform work without checking if we need to yield.929    while (workInProgress !== null) {930      performUnitOfWork(workInProgress);931    }932  }933  function renderRootConcurrent(root, lanes) {934    var prevExecutionContext = executionContext;935    executionContext |= RenderContext;936    var prevDispatcher = pushDispatcher(); // If the root or lanes have changed, throw out the existing stack937    // and prepare a fresh one. Otherwise we'll continue where we left off.938    if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) {939      resetRenderTimer();940      prepareFreshStack(root, lanes);941      startWorkOnPendingInteractions(root, lanes);942    }943    var prevInteractions = pushInteractions(root);944    {945      markRenderStarted(lanes);946    }947    do {948      try {949        workLoopConcurrent();950        break;951      } catch (thrownValue) {952        handleError(root, thrownValue);953      }954    } while (true);955    resetContextDependencies();956    {957      popInteractions(prevInteractions);958    }959    popDispatcher(prevDispatcher);960    executionContext = prevExecutionContext;961    if (workInProgress !== null) {962      // Still work remaining.963      {964        markRenderYielded();965      }966      return RootIncomplete;967    } else {968      // Completed the tree.969      {970        markRenderStopped();971      } // Set this to null to indicate there's no in-progress render.972      workInProgressRoot = null;973      workInProgressRootRenderLanes = NoLanes; // Return the final exit status.974      return workInProgressRootExitStatus;975    }976  }977  /** @noinline */978  function workLoopConcurrent() {979    // Perform work until Scheduler asks us to yield980    while (workInProgress !== null && !shouldYield()) {981      performUnitOfWork(workInProgress);982    }983  }984  function performUnitOfWork(unitOfWork) {985    // The current, flushed, state of this fiber is the alternate. Ideally986    // nothing should rely on this, but relying on it here means that we don't987    // need an additional field on the work in progress.988    var current = unitOfWork.alternate;989    setCurrentFiber(unitOfWork);990    var next;991    if ( (unitOfWork.mode & ProfileMode) !== NoMode) {992      startProfilerTimer(unitOfWork);993      next = beginWork$1(current, unitOfWork, subtreeRenderLanes);994      stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true);995    } else {996      next = beginWork$1(current, unitOfWork, subtreeRenderLanes);997    }998    resetCurrentFiber();999    unitOfWork.memoizedProps = unitOfWork.pendingProps;1000    if (next === null) {1001      // If this doesn't spawn new work, complete the current work.1002      completeUnitOfWork(unitOfWork);1003    } else {1004      workInProgress = next;1005    }1006    ReactCurrentOwner$2.current = null;1007  }1008  function completeUnitOfWork(unitOfWork) {1009    // Attempt to complete the current unit of work, then move to the next1010    // sibling. If there are no more siblings, return to the parent fiber.1011    var completedWork = unitOfWork;1012    do {1013      // The current, flushed, state of this fiber is the alternate. Ideally1014      // nothing should rely on this, but relying on it here means that we don't1015      // need an additional field on the work in progress.1016      var current = completedWork.alternate;1017      var returnFiber = completedWork.return; // Check if the work completed or if something threw.1018      if ((completedWork.flags & Incomplete) === NoFlags) {1019        setCurrentFiber(completedWork);1020        var next = void 0;1021        if ( (completedWork.mode & ProfileMode) === NoMode) {1022          next = completeWork(current, completedWork, subtreeRenderLanes);1023        } else {1024          startProfilerTimer(completedWork);1025          next = completeWork(current, completedWork, subtreeRenderLanes); // Update render duration assuming we didn't error.1026          stopProfilerTimerIfRunningAndRecordDelta(completedWork, false);1027        }1028        resetCurrentFiber();1029        if (next !== null) {1030          // Completing this fiber spawned new work. Work on that next.1031          workInProgress = next;1032          return;1033        }1034        resetChildLanes(completedWork);1035        if (returnFiber !== null && // Do not append effects to parents if a sibling failed to complete1036        (returnFiber.flags & Incomplete) === NoFlags) {1037          // Append all the effects of the subtree and this fiber onto the effect1038          // list of the parent. The completion order of the children affects the1039          // side-effect order.1040          if (returnFiber.firstEffect === null) {1041            returnFiber.firstEffect = completedWork.firstEffect;1042          }1043          if (completedWork.lastEffect !== null) {1044            if (returnFiber.lastEffect !== null) {1045              returnFiber.lastEffect.nextEffect = completedWork.firstEffect;1046            }1047            returnFiber.lastEffect = completedWork.lastEffect;1048          } // If this fiber had side-effects, we append it AFTER the children's1049          // side-effects. We can perform certain side-effects earlier if needed,1050          // by doing multiple passes over the effect list. We don't want to1051          // schedule our own side-effect on our own list because if end up1052          // reusing children we'll schedule this effect onto itself since we're1053          // at the end.1054          var flags = completedWork.flags; // Skip both NoWork and PerformedWork tags when creating the effect1055          // list. PerformedWork effect is read by React DevTools but shouldn't be1056          // committed.1057          if (flags > PerformedWork) {1058            if (returnFiber.lastEffect !== null) {1059              returnFiber.lastEffect.nextEffect = completedWork;1060            } else {1061              returnFiber.firstEffect = completedWork;1062            }1063            returnFiber.lastEffect = completedWork;1064          }1065        }1066      } else {1067        // This fiber did not complete because something threw. Pop values off1068        // the stack without entering the complete phase. If this is a boundary,1069        // capture values if possible.1070        var _next = unwindWork(completedWork); // Because this fiber did not complete, don't reset its expiration time.1071        if (_next !== null) {1072          // If completing this work spawned new work, do that next. We'll come1073          // back here again.1074          // Since we're restarting, remove anything that is not a host effect1075          // from the effect tag.1076          _next.flags &= HostEffectMask;1077          workInProgress = _next;1078          return;1079        }1080        if ( (completedWork.mode & ProfileMode) !== NoMode) {1081          // Record the render duration for the fiber that errored.1082          stopProfilerTimerIfRunningAndRecordDelta(completedWork, false); // Include the time spent working on failed children before continuing.1083          var actualDuration = completedWork.actualDuration;1084          var child = completedWork.child;1085          while (child !== null) {1086            actualDuration += child.actualDuration;1087            child = child.sibling;1088          }1089          completedWork.actualDuration = actualDuration;1090        }1091        if (returnFiber !== null) {1092          // Mark the parent fiber as incomplete and clear its effect list.1093          returnFiber.firstEffect = returnFiber.lastEffect = null;1094          returnFiber.flags |= Incomplete;1095        }1096      }1097      var siblingFiber = completedWork.sibling;1098      if (siblingFiber !== null) {1099        // If there is more work to do in this returnFiber, do that next.1100        workInProgress = siblingFiber;1101        return;1102      } // Otherwise, return to the parent1103      completedWork = returnFiber; // Update the next thing we're working on in case something throws.1104      workInProgress = completedWork;1105    } while (completedWork !== null); // We've reached the root.1106    if (workInProgressRootExitStatus === RootIncomplete) {1107      workInProgressRootExitStatus = RootCompleted;1108    }1109  }1110  function resetChildLanes(completedWork) {1111    if ( // TODO: Move this check out of the hot path by moving `resetChildLanes`1112    // to switch statement in `completeWork`.1113    (completedWork.tag === LegacyHiddenComponent || completedWork.tag === OffscreenComponent) && completedWork.memoizedState !== null && !includesSomeLane(subtreeRenderLanes, OffscreenLane) && (completedWork.mode & ConcurrentMode) !== NoLanes) {1114      // The children of this component are hidden. Don't bubble their1115      // expiration times.1116      return;1117    }1118    var newChildLanes = NoLanes; // Bubble up the earliest expiration time.1119    if ( (completedWork.mode & ProfileMode) !== NoMode) {1120      // In profiling mode, resetChildExpirationTime is also used to reset1121      // profiler durations.1122      var actualDuration = completedWork.actualDuration;1123      var treeBaseDuration = completedWork.selfBaseDuration; // When a fiber is cloned, its actualDuration is reset to 0. This value will1124      // only be updated if work is done on the fiber (i.e. it doesn't bailout).1125      // When work is done, it should bubble to the parent's actualDuration. If1126      // the fiber has not been cloned though, (meaning no work was done), then1127      // this value will reflect the amount of time spent working on a previous1128      // render. In that case it should not bubble. We determine whether it was1129      // cloned by comparing the child pointer.1130      var shouldBubbleActualDurations = completedWork.alternate === null || completedWork.child !== completedWork.alternate.child;1131      var child = completedWork.child;1132      while (child !== null) {1133        newChildLanes = mergeLanes(newChildLanes, mergeLanes(child.lanes, child.childLanes));1134        if (shouldBubbleActualDurations) {1135          actualDuration += child.actualDuration;1136        }1137        treeBaseDuration += child.treeBaseDuration;1138        child = child.sibling;1139      }1140      var isTimedOutSuspense = completedWork.tag === SuspenseComponent && completedWork.memoizedState !== null;1141      if (isTimedOutSuspense) {1142        // Don't count time spent in a timed out Suspense subtree as part of the base duration.1143        var primaryChildFragment = completedWork.child;1144        if (primaryChildFragment !== null) {1145          treeBaseDuration -= primaryChildFragment.treeBaseDuration;1146        }1147      }1148      completedWork.actualDuration = actualDuration;1149      completedWork.treeBaseDuration = treeBaseDuration;1150    } else {1151      var _child = completedWork.child;1152      while (_child !== null) {1153        newChildLanes = mergeLanes(newChildLanes, mergeLanes(_child.lanes, _child.childLanes));1154        _child = _child.sibling;1155      }1156    }1157    completedWork.childLanes = newChildLanes;1158  }1159  function commitRoot(root) {1160    var renderPriorityLevel = getCurrentPriorityLevel();1161    runWithPriority$1(ImmediatePriority$1, commitRootImpl.bind(null, root, renderPriorityLevel));1162    return null;1163  }1164  function commitRootImpl(root, renderPriorityLevel) {1165    do {1166      // `flushPassiveEffects` will call `flushSyncUpdateQueue` at the end, which1167      // means `flushPassiveEffects` will sometimes result in additional1168      // passive effects. So we need to keep flushing in a loop until there are1169      // no more pending effects.1170      // TODO: Might be better if `flushPassiveEffects` did not automatically1171      // flush synchronous work at the end, to avoid factoring hazards like this.1172      flushPassiveEffects();1173    } while (rootWithPendingPassiveEffects !== null);1174    flushRenderPhaseStrictModeWarningsInDEV();1175    if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {1176      {1177        throw Error( "Should not already be working." );1178      }1179    }1180    var finishedWork = root.finishedWork;1181    var lanes = root.finishedLanes;1182    {1183      markCommitStarted(lanes);1184    }1185    if (finishedWork === null) {1186      {1187        markCommitStopped();1188      }1189      return null;1190    }1191    root.finishedWork = null;1192    root.finishedLanes = NoLanes;1193    if (!(finishedWork !== root.current)) {1194      {1195        throw Error( "Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue." );1196      }1197    } // commitRoot never returns a continuation; it always finishes synchronously.1198    // So we can clear these now to allow a new callback to be scheduled.1199    root.callbackNode = null; // Update the first and last pending times on this root. The new first1200    // pending time is whatever is left on the root fiber.1201    var remainingLanes = mergeLanes(finishedWork.lanes, finishedWork.childLanes);1202    markRootFinished(root, remainingLanes); // Clear already finished discrete updates in case that a later call of1203    // `flushDiscreteUpdates` starts a useless render pass which may cancels1204    // a scheduled timeout.1205    if (rootsWithPendingDiscreteUpdates !== null) {1206      if (!hasDiscreteLanes(remainingLanes) && rootsWithPendingDiscreteUpdates.has(root)) {1207        rootsWithPendingDiscreteUpdates.delete(root);1208      }1209    }1210    if (root === workInProgressRoot) {1211      // We can reset these now that they are finished.1212      workInProgressRoot = null;1213      workInProgress = null;1214      workInProgressRootRenderLanes = NoLanes;1215    } // Get the list of effects.1216    var firstEffect;1217    if (finishedWork.flags > PerformedWork) {1218      // A fiber's effect list consists only of its children, not itself. So if1219      // the root has an effect, we need to add it to the end of the list. The1220      // resulting list is the set that would belong to the root's parent, if it1221      // had one; that is, all the effects in the tree including the root.1222      if (finishedWork.lastEffect !== null) {1223        finishedWork.lastEffect.nextEffect = finishedWork;1224        firstEffect = finishedWork.firstEffect;1225      } else {1226        firstEffect = finishedWork;1227      }1228    } else {1229      // There is no effect on the root.1230      firstEffect = finishedWork.firstEffect;1231    }1232    if (firstEffect !== null) {1233      var prevExecutionContext = executionContext;1234      executionContext |= CommitContext;1235      var prevInteractions = pushInteractions(root); // Reset this to null before calling lifecycles1236      ReactCurrentOwner$2.current = null; // The commit phase is broken into several sub-phases. We do a separate pass1237      // of the effect list for each phase: all mutation effects come before all1238      // layout effects, and so on.1239      // The first phase a "before mutation" phase. We use this phase to read the1240      // state of the host tree right before we mutate it. This is where1241      // getSnapshotBeforeUpdate is called.1242      focusedInstanceHandle = prepareForCommit(root.containerInfo);1243      shouldFireAfterActiveInstanceBlur = false;1244      nextEffect = firstEffect;1245      do {1246        {1247          invokeGuardedCallback(null, commitBeforeMutationEffects, null);1248          if (hasCaughtError()) {1249            if (!(nextEffect !== null)) {1250              {1251                throw Error( "Should be working on an effect." );1252              }1253            }1254            var error = clearCaughtError();1255            captureCommitPhaseError(nextEffect, error);1256            nextEffect = nextEffect.nextEffect;1257          }1258        }1259      } while (nextEffect !== null); // We no longer need to track the active instance fiber1260      focusedInstanceHandle = null;1261      {1262        // Mark the current commit time to be shared by all Profilers in this1263        // batch. This enables them to be grouped later.1264        recordCommitTime();1265      } // The next phase is the mutation phase, where we mutate the host tree.1266      nextEffect = firstEffect;1267      do {1268        {1269          invokeGuardedCallback(null, commitMutationEffects, null, root, renderPriorityLevel);1270          if (hasCaughtError()) {1271            if (!(nextEffect !== null)) {1272              {1273                throw Error( "Should be working on an effect." );1274              }1275            }1276            var _error = clearCaughtError();1277            captureCommitPhaseError(nextEffect, _error);1278            nextEffect = nextEffect.nextEffect;1279          }1280        }1281      } while (nextEffect !== null);1282      resetAfterCommit(root.containerInfo); // The work-in-progress tree is now the current tree. This must come after1283      // the mutation phase, so that the previous tree is still current during1284      // componentWillUnmount, but before the layout phase, so that the finished1285      // work is current during componentDidMount/Update.1286      root.current = finishedWork; // The next phase is the layout phase, where we call effects that read1287      // the host tree after it's been mutated. The idiomatic use case for this is1288      // layout, but class component lifecycles also fire here for legacy reasons.1289      nextEffect = firstEffect;1290      do {1291        {1292          invokeGuardedCallback(null, commitLayoutEffects, null, root, lanes);1293          if (hasCaughtError()) {1294            if (!(nextEffect !== null)) {1295              {1296                throw Error( "Should be working on an effect." );1297              }1298            }1299            var _error2 = clearCaughtError();1300            captureCommitPhaseError(nextEffect, _error2);1301            nextEffect = nextEffect.nextEffect;1302          }1303        }1304      } while (nextEffect !== null);1305      nextEffect = null; // Tell Scheduler to yield at the end of the frame, so the browser has an1306      // opportunity to paint.1307      requestPaint();1308      {1309        popInteractions(prevInteractions);1310      }1311      executionContext = prevExecutionContext;1312    } else {1313      // No effects.1314      root.current = finishedWork; // Measure these anyway so the flamegraph explicitly shows that there were1315      // no effects.1316      // TODO: Maybe there's a better way to report this.1317      {1318        recordCommitTime();1319      }1320    }1321    var rootDidHavePassiveEffects = rootDoesHavePassiveEffects;1322    if (rootDoesHavePassiveEffects) {1323      // This commit has passive effects. Stash a reference to them. But don't1324      // schedule a callback until after flushing layout work.1325      rootDoesHavePassiveEffects = false;1326      rootWithPendingPassiveEffects = root;1327      pendingPassiveEffectsLanes = lanes;1328      pendingPassiveEffectsRenderPriority = renderPriorityLevel;1329    } else {1330      // We are done with the effect chain at this point so let's clear the1331      // nextEffect pointers to assist with GC. If we have passive effects, we'll1332      // clear this in flushPassiveEffects.1333      nextEffect = firstEffect;1334      while (nextEffect !== null) {1335        var nextNextEffect = nextEffect.nextEffect;1336        nextEffect.nextEffect = null;1337        if (nextEffect.flags & Deletion) {1338          detachFiberAfterEffects(nextEffect);1339        }1340        nextEffect = nextNextEffect;1341      }1342    } // Read this again, since an effect might have updated it1343    remainingLanes = root.pendingLanes; // Check if there's remaining work on this root1344    if (remainingLanes !== NoLanes) {1345      {1346        if (spawnedWorkDuringRender !== null) {1347          var expirationTimes = spawnedWorkDuringRender;1348          spawnedWorkDuringRender = null;1349          for (var i = 0; i < expirationTimes.length; i++) {1350            scheduleInteractions(root, expirationTimes[i], root.memoizedInteractions);1351          }1352        }1353        schedulePendingInteractions(root, remainingLanes);1354      }1355    } else {1356      // If there's no remaining work, we can clear the set of already failed1357      // error boundaries.1358      legacyErrorBoundariesThatAlreadyFailed = null;1359    }1360    {1361      if (!rootDidHavePassiveEffects) {1362        // If there are no passive effects, then we can complete the pending interactions.1363        // Otherwise, we'll wait until after the passive effects are flushed.1364        // Wait to do this until after remaining work has been scheduled,1365        // so that we don't prematurely signal complete for interactions when there's e.g. hidden work.1366        finishPendingInteractions(root, lanes);1367      }1368    }1369    if (remainingLanes === SyncLane) {1370      // Count the number of times the root synchronously re-renders without1371      // finishing. If there are too many, it indicates an infinite update loop.1372      if (root === rootWithNestedUpdates) {1373        nestedUpdateCount++;1374      } else {1375        nestedUpdateCount = 0;1376        rootWithNestedUpdates = root;1377      }1378    } else {1379      nestedUpdateCount = 0;1380    }1381    onCommitRoot(finishedWork.stateNode, renderPriorityLevel);1382    {1383      onCommitRoot$1();1384    } // Always call this before exiting `commitRoot`, to ensure that any1385    // additional work on this root is scheduled.1386    ensureRootIsScheduled(root, now());1387    if (hasUncaughtError) {1388      hasUncaughtError = false;1389      var _error3 = firstUncaughtError;1390      firstUncaughtError = null;1391      throw _error3;1392    }1393    if ((executionContext & LegacyUnbatchedContext) !== NoContext) {1394      {1395        markCommitStopped();1396      } // This is a legacy edge case. We just committed the initial mount of1397      // a ReactDOM.render-ed root inside of batchedUpdates. The commit fired1398      // synchronously, but layout updates should be deferred until the end1399      // of the batch.1400      return null;1401    } // If layout work was scheduled, flush it now.1402    flushSyncCallbackQueue();1403    {1404      markCommitStopped();1405    }1406    return null;1407  }1408  function commitBeforeMutationEffects() {1409    while (nextEffect !== null) {1410      var current = nextEffect.alternate;1411      if (!shouldFireAfterActiveInstanceBlur && focusedInstanceHandle !== null) {1412        if ((nextEffect.flags & Deletion) !== NoFlags) {1413          if (doesFiberContain(nextEffect, focusedInstanceHandle)) {1414            shouldFireAfterActiveInstanceBlur = true;1415          }1416        } else {1417          // TODO: Move this out of the hot path using a dedicated effect tag.1418          if (nextEffect.tag === SuspenseComponent && isSuspenseBoundaryBeingHidden(current, nextEffect) && doesFiberContain(nextEffect, focusedInstanceHandle)) {1419            shouldFireAfterActiveInstanceBlur = true;1420          }1421        }1422      }1423      var flags = nextEffect.flags;1424      if ((flags & Snapshot) !== NoFlags) {1425        setCurrentFiber(nextEffect);1426        commitBeforeMutationLifeCycles(current, nextEffect);1427        resetCurrentFiber();1428      }1429      if ((flags & Passive) !== NoFlags) {1430        // If there are passive effects, schedule a callback to flush at1431        // the earliest opportunity.1432        if (!rootDoesHavePassiveEffects) {1433          rootDoesHavePassiveEffects = true;1434          scheduleCallback(NormalPriority$1, function () {1435            flushPassiveEffects();1436            return null;1437          });1438        }1439      }1440      nextEffect = nextEffect.nextEffect;1441    }1442  }1443  function commitMutationEffects(root, renderPriorityLevel) {1444    // TODO: Should probably move the bulk of this function to commitWork.1445    while (nextEffect !== null) {1446      setCurrentFiber(nextEffect);1447      var flags = nextEffect.flags;1448      if (flags & ContentReset) {1449        commitResetTextContent(nextEffect);1450      }1451      if (flags & Ref) {1452        var current = nextEffect.alternate;1453        if (current !== null) {1454          commitDetachRef(current);1455        }1456      } // The following switch statement is only concerned about placement,1457      // updates, and deletions. To avoid needing to add a case for every possible1458      // bitmap value, we remove the secondary effects from the effect tag and1459      // switch on that value.1460      var primaryFlags = flags & (Placement | Update | Deletion | Hydrating);1461      switch (primaryFlags) {1462        case Placement:1463          {1464            commitPlacement(nextEffect); // Clear the "placement" from effect tag so that we know that this is1465            // inserted, before any life-cycles like componentDidMount gets called.1466            // TODO: findDOMNode doesn't rely on this any more but isMounted does1467            // and isMounted is deprecated anyway so we should be able to kill this.1468            nextEffect.flags &= ~Placement;1469            break;1470          }1471        case PlacementAndUpdate:1472          {1473            // Placement1474            commitPlacement(nextEffect); // Clear the "placement" from effect tag so that we know that this is1475            // inserted, before any life-cycles like componentDidMount gets called.1476            nextEffect.flags &= ~Placement; // Update1477            var _current = nextEffect.alternate;1478            commitWork(_current, nextEffect);1479            break;1480          }1481        case Hydrating:1482          {1483            nextEffect.flags &= ~Hydrating;1484            break;1485          }1486        case HydratingAndUpdate:1487          {1488            nextEffect.flags &= ~Hydrating; // Update1489            var _current2 = nextEffect.alternate;1490            commitWork(_current2, nextEffect);1491            break;1492          }1493        case Update:1494          {1495            var _current3 = nextEffect.alternate;1496            commitWork(_current3, nextEffect);1497            break;1498          }1499        case Deletion:1500          {1501            commitDeletion(root, nextEffect);1502            break;1503          }1504      }1505      resetCurrentFiber();1506      nextEffect = nextEffect.nextEffect;1507    }1508  }1509  function commitLayoutEffects(root, committedLanes) {1510    {1511      markLayoutEffectsStarted(committedLanes);1512    } // TODO: Should probably move the bulk of this function to commitWork.1513    while (nextEffect !== null) {1514      setCurrentFiber(nextEffect);1515      var flags = nextEffect.flags;1516      if (flags & (Update | Callback)) {1517        var current = nextEffect.alternate;1518        commitLifeCycles(root, current, nextEffect);1519      }1520      {1521        if (flags & Ref) {1522          commitAttachRef(nextEffect);1523        }1524      }1525      resetCurrentFiber();1526      nextEffect = nextEffect.nextEffect;1527    }1528    {1529      markLayoutEffectsStopped();1530    }1531  }1532  function flushPassiveEffects() {1533    // Returns whether passive effects were flushed.1534    if (pendingPassiveEffectsRenderPriority !== NoPriority$1) {1535      var priorityLevel = pendingPassiveEffectsRenderPriority > NormalPriority$1 ? NormalPriority$1 : pendingPassiveEffectsRenderPriority;1536      pendingPassiveEffectsRenderPriority = NoPriority$1;1537      {1538        return runWithPriority$1(priorityLevel, flushPassiveEffectsImpl);1539      }1540    }1541    return false;1542  }1543  function enqueuePendingPassiveHookEffectMount(fiber, effect) {1544    pendingPassiveHookEffectsMount.push(effect, fiber);1545    if (!rootDoesHavePassiveEffects) {1546      rootDoesHavePassiveEffects = true;1547      scheduleCallback(NormalPriority$1, function () {1548        flushPassiveEffects();1549        return null;1550      });1551    }1552  }1553  function enqueuePendingPassiveHookEffectUnmount(fiber, effect) {1554    pendingPassiveHookEffectsUnmount.push(effect, fiber);1555    {1556      fiber.flags |= PassiveUnmountPendingDev;1557      var alternate = fiber.alternate;1558      if (alternate !== null) {1559        alternate.flags |= PassiveUnmountPendingDev;1560      }1561    }1562    if (!rootDoesHavePassiveEffects) {1563      rootDoesHavePassiveEffects = true;1564      scheduleCallback(NormalPriority$1, function () {1565        flushPassiveEffects();1566        return null;1567      });1568    }1569  }1570  function invokePassiveEffectCreate(effect) {1571    var create = effect.create;1572    effect.destroy = create();1573  }1574  function flushPassiveEffectsImpl() {1575    if (rootWithPendingPassiveEffects === null) {1576      return false;1577    }1578    var root = rootWithPendingPassiveEffects;1579    var lanes = pendingPassiveEffectsLanes;1580    rootWithPendingPassiveEffects = null;1581    pendingPassiveEffectsLanes = NoLanes;1582    if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {1583      {1584        throw Error( "Cannot flush passive effects while already rendering." );1585      }1586    }1587    {1588      markPassiveEffectsStarted(lanes);1589    }1590    {1591      isFlushingPassiveEffects = true;1592    }1593    var prevExecutionContext = executionContext;1594    executionContext |= CommitContext;1595    var prevInteractions = pushInteractions(root); // It's important that ALL pending passive effect destroy functions are called1596    // before ANY passive effect create functions are called.1597    // Otherwise effects in sibling components might interfere with each other.1598    // e.g. a destroy function in one component may unintentionally override a ref1599    // value set by a create function in another component.1600    // Layout effects have the same constraint.1601    // First pass: Destroy stale passive effects.1602    var unmountEffects = pendingPassiveHookEffectsUnmount;1603    pendingPassiveHookEffectsUnmount = [];1604    for (var i = 0; i < unmountEffects.length; i += 2) {1605      var _effect = unmountEffects[i];1606      var fiber = unmountEffects[i + 1];1607      var destroy = _effect.destroy;1608      _effect.destroy = undefined;1609      {1610        fiber.flags &= ~PassiveUnmountPendingDev;1611        var alternate = fiber.alternate;1612        if (alternate !== null) {1613          alternate.flags &= ~PassiveUnmountPendingDev;1614        }1615      }1616      if (typeof destroy === 'function') {1617        {1618          setCurrentFiber(fiber);1619          {1620            invokeGuardedCallback(null, destroy, null);1621          }1622          if (hasCaughtError()) {1623            if (!(fiber !== null)) {1624              {1625                throw Error( "Should be working on an effect." );1626              }1627            }1628            var error = clearCaughtError();1629            captureCommitPhaseError(fiber, error);1630          }1631          resetCurrentFiber();1632        }1633      }1634    } // Second pass: Create new passive effects.1635    var mountEffects = pendingPassiveHookEffectsMount;1636    pendingPassiveHookEffectsMount = [];1637    for (var _i = 0; _i < mountEffects.length; _i += 2) {1638      var _effect2 = mountEffects[_i];1639      var _fiber = mountEffects[_i + 1];1640      {1641        setCurrentFiber(_fiber);1642        {1643          invokeGuardedCallback(null, invokePassiveEffectCreate, null, _effect2);1644        }1645        if (hasCaughtError()) {1646          if (!(_fiber !== null)) {1647            {1648              throw Error( "Should be working on an effect." );1649            }1650          }1651          var _error4 = clearCaughtError();1652          captureCommitPhaseError(_fiber, _error4);1653        }1654        resetCurrentFiber();1655      }1656    } // Note: This currently assumes there are no passive effects on the root fiber1657    // because the root is not part of its own effect list.1658    // This could change in the future.1659    var effect = root.current.firstEffect;1660    while (effect !== null) {1661      var nextNextEffect = effect.nextEffect; // Remove nextEffect pointer to assist GC1662      effect.nextEffect = null;1663      if (effect.flags & Deletion) {1664        detachFiberAfterEffects(effect);1665      }1666      effect = nextNextEffect;1667    }1668    {1669      popInteractions(prevInteractions);1670      finishPendingInteractions(root, lanes);1671    }1672    {1673      isFlushingPassiveEffects = false;1674    }1675    {1676      markPassiveEffectsStopped();1677    }1678    executionContext = prevExecutionContext;1679    flushSyncCallbackQueue(); // If additional passive effects were scheduled, increment a counter. If this1680    // exceeds the limit, we'll fire a warning.1681    nestedPassiveUpdateCount = rootWithPendingPassiveEffects === null ? 0 : nestedPassiveUpdateCount + 1;1682    return true;1683  }1684  function isAlreadyFailedLegacyErrorBoundary(instance) {1685    return legacyErrorBoundariesThatAlreadyFailed !== null && legacyErrorBoundariesThatAlreadyFailed.has(instance);1686  }1687  function markLegacyErrorBoundaryAsFailed(instance) {1688    if (legacyErrorBoundariesThatAlreadyFailed === null) {1689      legacyErrorBoundariesThatAlreadyFailed = new Set([instance]);1690    } else {1691      legacyErrorBoundariesThatAlreadyFailed.add(instance);1692    }1693  }1694  function prepareToThrowUncaughtError(error) {1695    if (!hasUncaughtError) {1696      hasUncaughtError = true;1697      firstUncaughtError = error;1698    }1699  }1700  var onUncaughtError = prepareToThrowUncaughtError;1701  function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) {1702    var errorInfo = createCapturedValue(error, sourceFiber);1703    var update = createRootErrorUpdate(rootFiber, errorInfo, SyncLane);1704    enqueueUpdate(rootFiber, update);1705    var eventTime = requestEventTime();1706    var root = markUpdateLaneFromFiberToRoot(rootFiber, SyncLane);1707    if (root !== null) {1708      markRootUpdated(root, SyncLane, eventTime);1709      ensureRootIsScheduled(root, eventTime);1710      schedulePendingInteractions(root, SyncLane);1711    }1712  }1713  function captureCommitPhaseError(sourceFiber, error) {1714    if (sourceFiber.tag === HostRoot) {1715      // Error was thrown at the root. There is no parent, so the root1716      // itself should capture it.1717      captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error);1718      return;1719    }1720    var fiber = sourceFiber.return;1721    while (fiber !== null) {1722      if (fiber.tag === HostRoot) {1723        captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error);1724        return;1725      } else if (fiber.tag === ClassComponent) {1726        var ctor = fiber.type;1727        var instance = fiber.stateNode;1728        if (typeof ctor.getDerivedStateFromError === 'function' || typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance)) {1729          var errorInfo = createCapturedValue(error, sourceFiber);1730          var update = createClassErrorUpdate(fiber, errorInfo, SyncLane);1731          enqueueUpdate(fiber, update);1732          var eventTime = requestEventTime();1733          var root = markUpdateLaneFromFiberToRoot(fiber, SyncLane);1734          if (root !== null) {1735            markRootUpdated(root, SyncLane, eventTime);1736            ensureRootIsScheduled(root, eventTime);1737            schedulePendingInteractions(root, SyncLane);1738          } else {1739            // This component has already been unmounted.1740            // We can't schedule any follow up work for the root because the fiber is already unmounted,1741            // but we can still call the log-only boundary so the error isn't swallowed.1742            //1743            // TODO This is only a temporary bandaid for the old reconciler fork.1744            // We can delete this special case once the new fork is merged.1745            if (typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance)) {1746              try {1747                instance.componentDidCatch(error, errorInfo);1748              } catch (errorToIgnore) {// TODO Ignore this error? Rethrow it?1749                // This is kind of an edge case.1750              }1751            }1752          }1753          return;1754        }1755      }1756      fiber = fiber.return;1757    }1758  }1759  function pingSuspendedRoot(root, wakeable, pingedLanes) {1760    var pingCache = root.pingCache;1761    if (pingCache !== null) {1762      // The wakeable resolved, so we no longer need to memoize, because it will1763      // never be thrown again.1764      pingCache.delete(wakeable);1765    }1766    var eventTime = requestEventTime();1767    markRootPinged(root, pingedLanes);1768    if (workInProgressRoot === root && isSubsetOfLanes(workInProgressRootRenderLanes, pingedLanes)) {1769      // Received a ping at the same priority level at which we're currently1770      // rendering. We might want to restart this render. This should mirror1771      // the logic of whether or not a root suspends once it completes.1772      // TODO: If we're rendering sync either due to Sync, Batched or expired,1773      // we should probably never restart.1774      // If we're suspended with delay, or if it's a retry, we'll always suspend1775      // so we can always restart.1776      if (workInProgressRootExitStatus === RootSuspendedWithDelay || workInProgressRootExitStatus === RootSuspended && includesOnlyRetries(workInProgressRootRenderLanes) && now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) {1777        // Restart from the root.1778        prepareFreshStack(root, NoLanes);1779      } else {1780        // Even though we can't restart right now, we might get an1781        // opportunity later. So we mark this render as having a ping.1782        workInProgressRootPingedLanes = mergeLanes(workInProgressRootPingedLanes, pingedLanes);1783      }1784    }1785    ensureRootIsScheduled(root, eventTime);1786    schedulePendingInteractions(root, pingedLanes);1787  }1788  function retryTimedOutBoundary(boundaryFiber, retryLane) {1789    // The boundary fiber (a Suspense component or SuspenseList component)1790    // previously was rendered in its fallback state. One of the promises that1791    // suspended it has resolved, which means at least part of the tree was1792    // likely unblocked. Try rendering again, at a new expiration time.1793    if (retryLane === NoLane) {1794      retryLane = requestRetryLane(boundaryFiber);1795    } // TODO: Special case idle priority?1796    var eventTime = requestEventTime();1797    var root = markUpdateLaneFromFiberToRoot(boundaryFiber, retryLane);1798    if (root !== null) {1799      markRootUpdated(root, retryLane, eventTime);1800      ensureRootIsScheduled(root, eventTime);1801      schedulePendingInteractions(root, retryLane);1802    }1803  }1804  function retryDehydratedSuspenseBoundary(boundaryFiber) {1805    var suspenseState = boundaryFiber.memoizedState;1806    var retryLane = NoLane;1807    if (suspenseState !== null) {1808      retryLane = suspenseState.retryLane;1809    }1810    retryTimedOutBoundary(boundaryFiber, retryLane);1811  }1812  function resolveRetryWakeable(boundaryFiber, wakeable) {1813    var retryLane = NoLane; // Default1814    var retryCache;1815    {1816      switch (boundaryFiber.tag) {1817        case SuspenseComponent:1818          retryCache = boundaryFiber.stateNode;1819          var suspenseState = boundaryFiber.memoizedState;1820          if (suspenseState !== null) {1821            retryLane = suspenseState.retryLane;1822          }1823          break;1824        case SuspenseListComponent:1825          retryCache = boundaryFiber.stateNode;1826          break;1827        default:1828          {1829            {1830              throw Error( "Pinged unknown suspense boundary type. This is probably a bug in React." );1831            }1832          }1833      }1834    }1835    if (retryCache !== null) {1836      // The wakeable resolved, so we no longer need to memoize, because it will1837      // never be thrown again.1838      retryCache.delete(wakeable);1839    }1840    retryTimedOutBoundary(boundaryFiber, retryLane);1841  } // Computes the next Just Noticeable Difference (JND) boundary.1842  // The theory is that a person can't tell the difference between small differences in time.1843  // Therefore, if we wait a bit longer than necessary that won't translate to a noticeable1844  // difference in the experience. However, waiting for longer might mean that we can avoid1845  // showing an intermediate loading state. The longer we have already waited, the harder it1846  // is to tell small differences in time. Therefore, the longer we've already waited,1847  // the longer we can wait additionally. At some point we have to give up though.1848  // We pick a train model where the next boundary commits at a consistent schedule.1849  // These particular numbers are vague estimates. We expect to adjust them based on research.1850  function jnd(timeElapsed) {1851    return timeElapsed < 120 ? 120 : timeElapsed < 480 ? 480 : timeElapsed < 1080 ? 1080 : timeElapsed < 1920 ? 1920 : timeElapsed < 3000 ? 3000 : timeElapsed < 4320 ? 4320 : ceil(timeElapsed / 1960) * 1960;1852  }1853  function checkForNestedUpdates() {1854    if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {1855      nestedUpdateCount = 0;1856      rootWithNestedUpdates = null;1857      {1858        {1859          throw Error( "Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops." );1860        }1861      }1862    }1863    {1864      if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) {1865        nestedPassiveUpdateCount = 0;1866        error('Maximum update depth exceeded. This can happen when a component ' + "calls setState inside useEffect, but useEffect either doesn't " + 'have a dependency array, or one of the dependencies changes on ' + 'every render.');1867      }1868    }1869  }1870  function flushRenderPhaseStrictModeWarningsInDEV() {1871    {1872      ReactStrictModeWarnings.flushLegacyContextWarning();1873      {1874        ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings();1875      }1876    }1877  }1878  var didWarnStateUpdateForNotYetMountedComponent = null;1879  function warnAboutUpdateOnNotYetMountedFiberInDEV(fiber) {1880    {1881      if ((executionContext & RenderContext) !== NoContext) {1882        // We let the other warning about render phase updates deal with this one.1883        return;1884      }1885      if (!(fiber.mode & (BlockingMode | ConcurrentMode))) {1886        return;1887      }1888      var tag = fiber.tag;1889      if (tag !== IndeterminateComponent && tag !== HostRoot && tag !== ClassComponent && tag !== FunctionComponent && tag !== ForwardRef && tag !== MemoComponent && tag !== SimpleMemoComponent && tag !== Block) {1890        // Only warn for user-defined components, not internal ones like Suspense.1891        return;1892      } // We show the whole stack but dedupe on the top component's name because1893      // the problematic code almost always lies inside that component.1894      var componentName = getComponentName(fiber.type) || 'ReactComponent';1895      if (didWarnStateUpdateForNotYetMountedComponent !== null) {1896        if (didWarnStateUpdateForNotYetMountedComponent.has(componentName)) {1897          return;1898        }1899        didWarnStateUpdateForNotYetMountedComponent.add(componentName);1900      } else {1901        didWarnStateUpdateForNotYetMountedComponent = new Set([componentName]);1902      }1903      var previousFiber = current;1904      try {1905        setCurrentFiber(fiber);1906        error("Can't perform a React state update on a component that hasn't mounted yet. " + 'This indicates that you have a side-effect in your render function that ' + 'asynchronously later calls tries to update the component. Move this work to ' + 'useEffect instead.');1907      } finally {1908        if (previousFiber) {1909          setCurrentFiber(fiber);1910        } else {1911          resetCurrentFiber();1912        }1913      }1914    }1915  }1916  var didWarnStateUpdateForUnmountedComponent = null;1917  function warnAboutUpdateOnUnmountedFiberInDEV(fiber) {1918    {1919      var tag = fiber.tag;1920      if (tag !== HostRoot && tag !== ClassComponent && tag !== FunctionComponent && tag !== ForwardRef && tag !== MemoComponent && tag !== SimpleMemoComponent && tag !== Block) {1921        // Only warn for user-defined components, not internal ones like Suspense.1922        return;1923      } // If there are pending passive effects unmounts for this Fiber,1924      // we can assume that they would have prevented this update.1925      if ((fiber.flags & PassiveUnmountPendingDev) !== NoFlags) {1926        return;1927      } // We show the whole stack but dedupe on the top component's name because1928      // the problematic code almost always lies inside that component.1929      var componentName = getComponentName(fiber.type) || 'ReactComponent';1930      if (didWarnStateUpdateForUnmountedComponent !== null) {1931        if (didWarnStateUpdateForUnmountedComponent.has(componentName)) {1932          return;1933        }1934        didWarnStateUpdateForUnmountedComponent.add(componentName);1935      } else {1936        didWarnStateUpdateForUnmountedComponent = new Set([componentName]);1937      }1938      if (isFlushingPassiveEffects) ; else {1939        var previousFiber = current;1940        try {1941          setCurrentFiber(fiber);1942          error("Can't perform a React state update on an unmounted component. This " + 'is a no-op, but it indicates a memory leak in your application. To ' + 'fix, cancel all subscriptions and asynchronous tasks in %s.', tag === ClassComponent ? 'the componentWillUnmount method' : 'a useEffect cleanup function');1943        } finally {1944          if (previousFiber) {1945            setCurrentFiber(fiber);1946          } else {1947            resetCurrentFiber();1948          }1949        }1950      }1951    }1952  }1953  var beginWork$1;1954  {1955    var dummyFiber = null;1956    beginWork$1 = function (current, unitOfWork, lanes) {1957      // If a component throws an error, we replay it again in a synchronously1958      // dispatched event, so that the debugger will treat it as an uncaught1959      // error See ReactErrorUtils for more information.1960      // Before entering the begin phase, copy the work-in-progress onto a dummy1961      // fiber. If beginWork throws, we'll use this to reset the state.1962      var originalWorkInProgressCopy = assignFiberPropertiesInDEV(dummyFiber, unitOfWork);1963      try {1964        return beginWork(current, unitOfWork, lanes);1965      } catch (originalError) {1966        if (originalError !== null && typeof originalError === 'object' && typeof originalError.then === 'function') {1967          // Don't replay promises. Treat everything else like an error.1968          throw originalError;1969        } // Keep this code in sync with handleError; any changes here must have1970        // corresponding changes there.1971        resetContextDependencies();1972        resetHooksAfterThrow(); // Don't reset current debug fiber, since we're about to work on the1973        // same fiber again.1974        // Unwind the failed stack frame1975        unwindInterruptedWork(unitOfWork); // Restore the original properties of the fiber.1976        assignFiberPropertiesInDEV(unitOfWork, originalWorkInProgressCopy);1977        if ( unitOfWork.mode & ProfileMode) {1978          // Reset the profiler timer.1979          startProfilerTimer(unitOfWork);1980        } // Run beginWork again.1981        invokeGuardedCallback(null, beginWork, null, current, unitOfWork, lanes);1982        if (hasCaughtError()) {1983          var replayError = clearCaughtError(); // `invokeGuardedCallback` sometimes sets an expando `_suppressLogging`.1984          // Rethrow this error instead of the original one.1985          throw replayError;1986        } else {1987          // This branch is reachable if the render phase is impure.1988          throw originalError;1989        }1990      }1991    };1992  }1993  var didWarnAboutUpdateInRender = false;1994  var didWarnAboutUpdateInRenderForAnotherComponent;1995  {1996    didWarnAboutUpdateInRenderForAnotherComponent = new Set();1997  }1998  function warnAboutRenderPhaseUpdatesInDEV(fiber) {1999    {2000      if (isRendering && (executionContext & RenderContext) !== NoContext && !getIsUpdatingOpaqueValueInRenderPhaseInDEV()) {2001        switch (fiber.tag) {2002          case FunctionComponent:2003          case ForwardRef:2004          case SimpleMemoComponent:2005            {2006              var renderingComponentName = workInProgress && getComponentName(workInProgress.type) || 'Unknown'; // Dedupe by the rendering component because it's the one that needs to be fixed.2007              var dedupeKey = renderingComponentName;2008              if (!didWarnAboutUpdateInRenderForAnotherComponent.has(dedupeKey)) {2009                didWarnAboutUpdateInRenderForAnotherComponent.add(dedupeKey);2010                var setStateComponentName = getComponentName(fiber.type) || 'Unknown';2011                error('Cannot update a component (`%s`) while rendering a ' + 'different component (`%s`). To locate the bad setState() call inside `%s`, ' + 'follow the stack trace as described in https://reactjs.org/link/setstate-in-render', setStateComponentName, renderingComponentName, renderingComponentName);2012              }...ReactFiberWorkLoop.new.js
Source:ReactFiberWorkLoop.new.js  
...403  lane: Lane,404  eventTime: number,405): FiberRoot | null {406  checkForNestedUpdates();407  warnAboutRenderPhaseUpdatesInDEV(fiber);408  const root = markUpdateLaneFromFiberToRoot(fiber, lane);409  if (root === null) {410    return null;411  }412  if (enableUpdaterTracking) {413    if (isDevToolsPresent) {414      addFiberToLanesMap(root, fiber, lane);415    }416  }417  // Mark that the root has a pending update.418  markRootUpdated(root, lane, eventTime);419  if (enableProfilerTimer && enableProfilerNestedUpdateScheduledHook) {420    if (421      (executionContext & CommitContext) !== NoContext &&422      root === rootCommittingMutationOrLayoutEffects423    ) {424      if (fiber.mode & ProfileMode) {425        let current = fiber;426        while (current !== null) {427          if (current.tag === Profiler) {428            const {id, onNestedUpdateScheduled} = current.memoizedProps;429            if (typeof onNestedUpdateScheduled === 'function') {430              onNestedUpdateScheduled(id);431            }432          }433          current = current.return;434        }435      }436    }437  }438  // TODO: Consolidate with `isInterleavedUpdate` check439  if (root === workInProgressRoot) {440    // Received an update to a tree that's in the middle of rendering. Mark441    // that there was an interleaved update work on this root. Unless the442    // `deferRenderPhaseUpdateToNextBatch` flag is off and this is a render443    // phase update. In that case, we don't treat render phase updates as if444    // they were interleaved, for backwards compat reasons.445    if (446      deferRenderPhaseUpdateToNextBatch ||447      (executionContext & RenderContext) === NoContext448    ) {449      workInProgressRootUpdatedLanes = mergeLanes(450        workInProgressRootUpdatedLanes,451        lane,452      );453    }454    if (workInProgressRootExitStatus === RootSuspendedWithDelay) {455      // The root already suspended with a delay, which means this render456      // definitely won't finish. Since we have a new update, let's mark it as457      // suspended now, right before marking the incoming update. This has the458      // effect of interrupting the current render and switching to the update.459      // TODO: Make sure this doesn't override pings that happen while we've460      // already started rendering.461      markRootSuspended(root, workInProgressRootRenderLanes);462    }463  }464  ensureRootIsScheduled(root, eventTime);465  if (466    lane === SyncLane &&467    executionContext === NoContext &&468    (fiber.mode & ConcurrentMode) === NoMode &&469    // Treat `act` as if it's inside `batchedUpdates`, even in legacy mode.470    !(__DEV__ && ReactCurrentActQueue.isBatchingLegacy)471  ) {472    // Flush the synchronous work now, unless we're already working or inside473    // a batch. This is intentionally inside scheduleUpdateOnFiber instead of474    // scheduleCallbackForFiber to preserve the ability to schedule a callback475    // without immediately flushing it. We only do this for user-initiated476    // updates, to preserve historical behavior of legacy mode.477    resetRenderTimer();478    flushSyncCallbacksOnlyInLegacyMode();479  }480  return root;481}482// This is split into a separate function so we can mark a fiber with pending483// work without treating it as a typical update that originates from an event;484// e.g. retrying a Suspense boundary isn't an update, but it does schedule work485// on a fiber.486function markUpdateLaneFromFiberToRoot(487  sourceFiber: Fiber,488  lane: Lane,489): FiberRoot | null {490  // Update the source fiber's lanes491  sourceFiber.lanes = mergeLanes(sourceFiber.lanes, lane);492  let alternate = sourceFiber.alternate;493  if (alternate !== null) {494    alternate.lanes = mergeLanes(alternate.lanes, lane);495  }496  if (__DEV__) {497    if (498      alternate === null &&499      (sourceFiber.flags & (Placement | Hydrating)) !== NoFlags500    ) {501      warnAboutUpdateOnNotYetMountedFiberInDEV(sourceFiber);502    }503  }504  // Walk the parent path to the root and update the child lanes.505  let node = sourceFiber;506  let parent = sourceFiber.return;507  while (parent !== null) {508    parent.childLanes = mergeLanes(parent.childLanes, lane);509    alternate = parent.alternate;510    if (alternate !== null) {511      alternate.childLanes = mergeLanes(alternate.childLanes, lane);512    } else {513      if (__DEV__) {514        if ((parent.flags & (Placement | Hydrating)) !== NoFlags) {515          warnAboutUpdateOnNotYetMountedFiberInDEV(sourceFiber);516        }517      }518    }519    node = parent;520    parent = parent.return;521  }522  if (node.tag === HostRoot) {523    const root: FiberRoot = node.stateNode;524    return root;525  } else {526    return null;527  }528}529export function isInterleavedUpdate(fiber: Fiber, lane: Lane) {530  return (531    // TODO: Optimize slightly by comparing to root that fiber belongs to.532    // Requires some refactoring. Not a big deal though since it's rare for533    // concurrent apps to have more than a single root.534    workInProgressRoot !== null &&535    (fiber.mode & ConcurrentMode) !== NoMode &&536    // If this is a render phase update (i.e. UNSAFE_componentWillReceiveProps),537    // then don't treat this as an interleaved update. This pattern is538    // accompanied by a warning but we haven't fully deprecated it yet. We can539    // remove once the deferRenderPhaseUpdateToNextBatch flag is enabled.540    (deferRenderPhaseUpdateToNextBatch ||541      (executionContext & RenderContext) === NoContext)542  );543}544// Use this function to schedule a task for a root. There's only one task per545// root; if a task was already scheduled, we'll check to make sure the priority546// of the existing task is the same as the priority of the next level that the547// root has work on. This function is called on every update, and right before548// exiting a task.549function ensureRootIsScheduled(root: FiberRoot, currentTime: number) {550  const existingCallbackNode = root.callbackNode;551  // Check if any lanes are being starved by other work. If so, mark them as552  // expired so we know to work on those next.553  markStarvedLanesAsExpired(root, currentTime);554  // Determine the next lanes to work on, and their priority.555  const nextLanes = getNextLanes(556    root,557    root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes,558  );559  if (nextLanes === NoLanes) {560    // Special case: There's nothing to work on.561    if (existingCallbackNode !== null) {562      cancelCallback(existingCallbackNode);563    }564    root.callbackNode = null;565    root.callbackPriority = NoLane;566    return;567  }568  // We use the highest priority lane to represent the priority of the callback.569  const newCallbackPriority = getHighestPriorityLane(nextLanes);570  // Check if there's an existing task. We may be able to reuse it.571  const existingCallbackPriority = root.callbackPriority;572  if (573    existingCallbackPriority === newCallbackPriority &&574    // Special case related to `act`. If the currently scheduled task is a575    // Scheduler task, rather than an `act` task, cancel it and re-scheduled576    // on the `act` queue.577    !(578      __DEV__ &&579      ReactCurrentActQueue.current !== null &&580      existingCallbackNode !== fakeActCallbackNode581    )582  ) {583    if (__DEV__) {584      // If we're going to re-use an existing task, it needs to exist.585      // Assume that discrete update microtasks are non-cancellable and null.586      // TODO: Temporary until we confirm this warning is not fired.587      if (588        existingCallbackNode == null &&589        existingCallbackPriority !== SyncLane590      ) {591        console.error(592          'Expected scheduled callback to exist. This error is likely caused by a bug in React. Please file an issue.',593        );594      }595    }596    // The priority hasn't changed. We can reuse the existing task. Exit.597    return;598  }599  if (existingCallbackNode != null) {600    // Cancel the existing callback. We'll schedule a new one below.601    cancelCallback(existingCallbackNode);602  }603  // Schedule a new callback.604  let newCallbackNode;605  if (newCallbackPriority === SyncLane) {606    // Special case: Sync React callbacks are scheduled on a special607    // internal queue608    if (root.tag === LegacyRoot) {609      if (__DEV__ && ReactCurrentActQueue.isBatchingLegacy !== null) {610        ReactCurrentActQueue.didScheduleLegacyUpdate = true;611      }612      scheduleLegacySyncCallback(performSyncWorkOnRoot.bind(null, root));613    } else {614      scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root));615    }616    if (supportsMicrotasks) {617      // Flush the queue in a microtask.618      if (__DEV__ && ReactCurrentActQueue.current !== null) {619        // Inside `act`, use our internal `act` queue so that these get flushed620        // at the end of the current scope even when using the sync version621        // of `act`.622        ReactCurrentActQueue.current.push(flushSyncCallbacks);623      } else {624        scheduleMicrotask(flushSyncCallbacks);625      }626    } else {627      // Flush the queue in an Immediate task.628      scheduleCallback(ImmediateSchedulerPriority, flushSyncCallbacks);629    }630    newCallbackNode = null;631  } else {632    let schedulerPriorityLevel;633    switch (lanesToEventPriority(nextLanes)) {634      case DiscreteEventPriority:635        schedulerPriorityLevel = ImmediateSchedulerPriority;636        break;637      case ContinuousEventPriority:638        schedulerPriorityLevel = UserBlockingSchedulerPriority;639        break;640      case DefaultEventPriority:641        schedulerPriorityLevel = NormalSchedulerPriority;642        break;643      case IdleEventPriority:644        schedulerPriorityLevel = IdleSchedulerPriority;645        break;646      default:647        schedulerPriorityLevel = NormalSchedulerPriority;648        break;649    }650    newCallbackNode = scheduleCallback(651      schedulerPriorityLevel,652      performConcurrentWorkOnRoot.bind(null, root),653    );654  }655  root.callbackPriority = newCallbackPriority;656  root.callbackNode = newCallbackNode;657}658// This is the entry point for every concurrent task, i.e. anything that659// goes through Scheduler.660function performConcurrentWorkOnRoot(root, didTimeout) {661  if (enableProfilerTimer && enableProfilerNestedUpdatePhase) {662    resetNestedUpdateFlag();663  }664  // Since we know we're in a React event, we can clear the current665  // event time. The next update will compute a new event time.666  currentEventTime = NoTimestamp;667  currentEventTransitionLane = NoLanes;668  invariant(669    (executionContext & (RenderContext | CommitContext)) === NoContext,670    'Should not already be working.',671  );672  // Flush any pending passive effects before deciding which lanes to work on,673  // in case they schedule additional work.674  const originalCallbackNode = root.callbackNode;675  const didFlushPassiveEffects = flushPassiveEffects();676  if (didFlushPassiveEffects) {677    // Something in the passive effect phase may have canceled the current task.678    // Check if the task node for this root was changed.679    if (root.callbackNode !== originalCallbackNode) {680      // The current task was canceled. Exit. We don't need to call681      // `ensureRootIsScheduled` because the check above implies either that682      // there's a new task, or that there's no remaining work on this root.683      return null;684    } else {685      // Current task was not canceled. Continue.686    }687  }688  // Determine the next lanes to work on, using the fields stored689  // on the root.690  let lanes = getNextLanes(691    root,692    root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes,693  );694  if (lanes === NoLanes) {695    // Defensive coding. This is never expected to happen.696    return null;697  }698  // We disable time-slicing in some cases: if the work has been CPU-bound699  // for too long ("expired" work, to prevent starvation), or we're in700  // sync-updates-by-default mode.701  // TODO: We only check `didTimeout` defensively, to account for a Scheduler702  // bug we're still investigating. Once the bug in Scheduler is fixed,703  // we can remove this, since we track expiration ourselves.704  let exitStatus =705    shouldTimeSlice(root, lanes) &&706    (disableSchedulerTimeoutInWorkLoop || !didTimeout)707      ? renderRootConcurrent(root, lanes)708      : renderRootSync(root, lanes);709  if (exitStatus !== RootIncomplete) {710    if (exitStatus === RootErrored) {711      const prevExecutionContext = executionContext;712      executionContext |= RetryAfterError;713      // If an error occurred during hydration,714      // discard server response and fall back to client side render.715      if (root.hydrate) {716        root.hydrate = false;717        if (__DEV__) {718          errorHydratingContainer(root.containerInfo);719        }720        clearContainer(root.containerInfo);721      }722      // If something threw an error, try rendering one more time. We'll render723      // synchronously to block concurrent data mutations, and we'll includes724      // all pending updates are included. If it still fails after the second725      // attempt, we'll give up and commit the resulting tree.726      const errorRetryLanes = getLanesToRetrySynchronouslyOnError(root);727      if (errorRetryLanes !== NoLanes) {728        lanes = errorRetryLanes;729        exitStatus = renderRootSync(root, errorRetryLanes);730      }731      executionContext = prevExecutionContext;732    }733    if (exitStatus === RootFatalErrored) {734      const fatalError = workInProgressRootFatalError;735      prepareFreshStack(root, NoLanes);736      markRootSuspended(root, lanes);737      ensureRootIsScheduled(root, now());738      throw fatalError;739    }740    // We now have a consistent tree. The next step is either to commit it,741    // or, if something suspended, wait to commit it after a timeout.742    const finishedWork: Fiber = (root.current.alternate: any);743    root.finishedWork = finishedWork;744    root.finishedLanes = lanes;745    finishConcurrentRender(root, exitStatus, lanes);746  }747  ensureRootIsScheduled(root, now());748  if (root.callbackNode === originalCallbackNode) {749    // The task node scheduled for this root is the same one that's750    // currently executed. Need to return a continuation.751    return performConcurrentWorkOnRoot.bind(null, root);752  }753  return null;754}755function finishConcurrentRender(root, exitStatus, lanes) {756  switch (exitStatus) {757    case RootIncomplete:758    case RootFatalErrored: {759      invariant(false, 'Root did not complete. This is a bug in React.');760    }761    // Flow knows about invariant, so it complains if I add a break762    // statement, but eslint doesn't know about invariant, so it complains763    // if I do. eslint-disable-next-line no-fallthrough764    case RootErrored: {765      // We should have already attempted to retry this tree. If we reached766      // this point, it errored again. Commit it.767      commitRoot(root);768      break;769    }770    case RootSuspended: {771      markRootSuspended(root, lanes);772      // We have an acceptable loading state. We need to figure out if we773      // should immediately commit it or wait a bit.774      if (775        includesOnlyRetries(lanes) &&776        // do not delay if we're inside an act() scope777        !shouldForceFlushFallbacksInDEV()778      ) {779        // This render only included retries, no updates. Throttle committing780        // retries so that we don't show too many loading states too quickly.781        const msUntilTimeout =782          globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now();783        // Don't bother with a very short suspense time.784        if (msUntilTimeout > 10) {785          const nextLanes = getNextLanes(root, NoLanes);786          if (nextLanes !== NoLanes) {787            // There's additional work on this root.788            break;789          }790          const suspendedLanes = root.suspendedLanes;791          if (!isSubsetOfLanes(suspendedLanes, lanes)) {792            // We should prefer to render the fallback of at the last793            // suspended level. Ping the last suspended level to try794            // rendering it again.795            // FIXME: What if the suspended lanes are Idle? Should not restart.796            const eventTime = requestEventTime();797            markRootPinged(root, suspendedLanes, eventTime);798            break;799          }800          // The render is suspended, it hasn't timed out, and there's no801          // lower priority work to do. Instead of committing the fallback802          // immediately, wait for more data to arrive.803          root.timeoutHandle = scheduleTimeout(804            commitRoot.bind(null, root),805            msUntilTimeout,806          );807          break;808        }809      }810      // The work expired. Commit immediately.811      commitRoot(root);812      break;813    }814    case RootSuspendedWithDelay: {815      markRootSuspended(root, lanes);816      if (includesOnlyTransitions(lanes)) {817        // This is a transition, so we should exit without committing a818        // placeholder and without scheduling a timeout. Delay indefinitely819        // until we receive more data.820        break;821      }822      if (!shouldForceFlushFallbacksInDEV()) {823        // This is not a transition, but we did trigger an avoided state.824        // Schedule a placeholder to display after a short delay, using the Just825        // Noticeable Difference.826        // TODO: Is the JND optimization worth the added complexity? If this is827        // the only reason we track the event time, then probably not.828        // Consider removing.829        const mostRecentEventTime = getMostRecentEventTime(root, lanes);830        const eventTimeMs = mostRecentEventTime;831        const timeElapsedMs = now() - eventTimeMs;832        const msUntilTimeout = jnd(timeElapsedMs) - timeElapsedMs;833        // Don't bother with a very short suspense time.834        if (msUntilTimeout > 10) {835          // Instead of committing the fallback immediately, wait for more data836          // to arrive.837          root.timeoutHandle = scheduleTimeout(838            commitRoot.bind(null, root),839            msUntilTimeout,840          );841          break;842        }843      }844      // Commit the placeholder.845      commitRoot(root);846      break;847    }848    case RootCompleted: {849      // The work completed. Ready to commit.850      commitRoot(root);851      break;852    }853    default: {854      invariant(false, 'Unknown root exit status.');855    }856  }857}858function markRootSuspended(root, suspendedLanes) {859  // When suspending, we should always exclude lanes that were pinged or (more860  // rarely, since we try to avoid it) updated during the render phase.861  // TODO: Lol maybe there's a better way to factor this besides this862  // obnoxiously named function :)863  suspendedLanes = removeLanes(suspendedLanes, workInProgressRootPingedLanes);864  suspendedLanes = removeLanes(suspendedLanes, workInProgressRootUpdatedLanes);865  markRootSuspended_dontCallThisOneDirectly(root, suspendedLanes);866}867// This is the entry point for synchronous tasks that don't go868// through Scheduler869function performSyncWorkOnRoot(root) {870  if (enableProfilerTimer && enableProfilerNestedUpdatePhase) {871    syncNestedUpdateFlag();872  }873  invariant(874    (executionContext & (RenderContext | CommitContext)) === NoContext,875    'Should not already be working.',876  );877  flushPassiveEffects();878  let lanes = getNextLanes(root, NoLanes);879  if (!includesSomeLane(lanes, SyncLane)) {880    // There's no remaining sync work left.881    ensureRootIsScheduled(root, now());882    return null;883  }884  let exitStatus = renderRootSync(root, lanes);885  if (root.tag !== LegacyRoot && exitStatus === RootErrored) {886    const prevExecutionContext = executionContext;887    executionContext |= RetryAfterError;888    // If an error occurred during hydration,889    // discard server response and fall back to client side render.890    if (root.hydrate) {891      root.hydrate = false;892      if (__DEV__) {893        errorHydratingContainer(root.containerInfo);894      }895      clearContainer(root.containerInfo);896    }897    // If something threw an error, try rendering one more time. We'll render898    // synchronously to block concurrent data mutations, and we'll includes899    // all pending updates are included. If it still fails after the second900    // attempt, we'll give up and commit the resulting tree.901    const errorRetryLanes = getLanesToRetrySynchronouslyOnError(root);902    if (errorRetryLanes !== NoLanes) {903      lanes = errorRetryLanes;904      exitStatus = renderRootSync(root, lanes);905    }906    executionContext = prevExecutionContext;907  }908  if (exitStatus === RootFatalErrored) {909    const fatalError = workInProgressRootFatalError;910    prepareFreshStack(root, NoLanes);911    markRootSuspended(root, lanes);912    ensureRootIsScheduled(root, now());913    throw fatalError;914  }915  // We now have a consistent tree. Because this is a sync render, we916  // will commit it even if something suspended.917  const finishedWork: Fiber = (root.current.alternate: any);918  root.finishedWork = finishedWork;919  root.finishedLanes = lanes;920  commitRoot(root);921  // Before exiting, make sure there's a callback scheduled for the next922  // pending level.923  ensureRootIsScheduled(root, now());924  return null;925}926export function flushRoot(root: FiberRoot, lanes: Lanes) {927  if (lanes !== NoLanes) {928    markRootEntangled(root, mergeLanes(lanes, SyncLane));929    ensureRootIsScheduled(root, now());930    if ((executionContext & (RenderContext | CommitContext)) === NoContext) {931      resetRenderTimer();932      flushSyncCallbacks();933    }934  }935}936export function getExecutionContext(): ExecutionContext {937  return executionContext;938}939export function deferredUpdates<A>(fn: () => A): A {940  const previousPriority = getCurrentUpdatePriority();941  const prevTransition = ReactCurrentBatchConfig.transition;942  try {943    ReactCurrentBatchConfig.transition = 0;944    setCurrentUpdatePriority(DefaultEventPriority);945    return fn();946  } finally {947    setCurrentUpdatePriority(previousPriority);948    ReactCurrentBatchConfig.transition = prevTransition;949  }950}951export function batchedUpdates<A, R>(fn: A => R, a: A): R {952  const prevExecutionContext = executionContext;953  executionContext |= BatchedContext;954  try {955    return fn(a);956  } finally {957    executionContext = prevExecutionContext;958    // If there were legacy sync updates, flush them at the end of the outer959    // most batchedUpdates-like method.960    if (961      executionContext === NoContext &&962      // Treat `act` as if it's inside `batchedUpdates`, even in legacy mode.963      !(__DEV__ && ReactCurrentActQueue.isBatchingLegacy)964    ) {965      resetRenderTimer();966      flushSyncCallbacksOnlyInLegacyMode();967    }968  }969}970export function discreteUpdates<A, B, C, D, R>(971  fn: (A, B, C, D) => R,972  a: A,973  b: B,974  c: C,975  d: D,976): R {977  const previousPriority = getCurrentUpdatePriority();978  const prevTransition = ReactCurrentBatchConfig.transition;979  try {980    ReactCurrentBatchConfig.transition = 0;981    setCurrentUpdatePriority(DiscreteEventPriority);982    return fn(a, b, c, d);983  } finally {984    setCurrentUpdatePriority(previousPriority);985    ReactCurrentBatchConfig.transition = prevTransition;986    if (executionContext === NoContext) {987      resetRenderTimer();988    }989  }990}991// Overload the definition to the two valid signatures.992// Warning, this opts-out of checking the function body.993declare function flushSyncWithoutWarningIfAlreadyRendering<R>(fn: () => R): R;994// eslint-disable-next-line no-redeclare995declare function flushSyncWithoutWarningIfAlreadyRendering(): void;996// eslint-disable-next-line no-redeclare997export function flushSyncWithoutWarningIfAlreadyRendering(fn) {998  // In legacy mode, we flush pending passive effects at the beginning of the999  // next event, not at the end of the previous one.1000  if (1001    rootWithPendingPassiveEffects !== null &&1002    rootWithPendingPassiveEffects.tag === LegacyRoot &&1003    (executionContext & (RenderContext | CommitContext)) === NoContext1004  ) {1005    flushPassiveEffects();1006  }1007  const prevExecutionContext = executionContext;1008  executionContext |= BatchedContext;1009  const prevTransition = ReactCurrentBatchConfig.transition;1010  const previousPriority = getCurrentUpdatePriority();1011  try {1012    ReactCurrentBatchConfig.transition = 0;1013    setCurrentUpdatePriority(DiscreteEventPriority);1014    if (fn) {1015      return fn();1016    } else {1017      return undefined;1018    }1019  } finally {1020    setCurrentUpdatePriority(previousPriority);1021    ReactCurrentBatchConfig.transition = prevTransition;1022    executionContext = prevExecutionContext;1023    // Flush the immediate callbacks that were scheduled during this batch.1024    // Note that this will happen even if batchedUpdates is higher up1025    // the stack.1026    if ((executionContext & (RenderContext | CommitContext)) === NoContext) {1027      flushSyncCallbacks();1028    }1029  }1030}1031// Overload the definition to the two valid signatures.1032// Warning, this opts-out of checking the function body.1033declare function flushSync<R>(fn: () => R): R;1034// eslint-disable-next-line no-redeclare1035declare function flushSync(): void;1036// eslint-disable-next-line no-redeclare1037export function flushSync(fn) {1038  if (__DEV__) {1039    if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {1040      console.error(1041        'flushSync was called from inside a lifecycle method. React cannot ' +1042          'flush when React is already rendering. Consider moving this call to ' +1043          'a scheduler task or micro task.',1044      );1045    }1046  }1047  return flushSyncWithoutWarningIfAlreadyRendering(fn);1048}1049export function flushControlled(fn: () => mixed): void {1050  const prevExecutionContext = executionContext;1051  executionContext |= BatchedContext;1052  const prevTransition = ReactCurrentBatchConfig.transition;1053  const previousPriority = getCurrentUpdatePriority();1054  try {1055    ReactCurrentBatchConfig.transition = 0;1056    setCurrentUpdatePriority(DiscreteEventPriority);1057    fn();1058  } finally {1059    setCurrentUpdatePriority(previousPriority);1060    ReactCurrentBatchConfig.transition = prevTransition;1061    executionContext = prevExecutionContext;1062    if (executionContext === NoContext) {1063      // Flush the immediate callbacks that were scheduled during this batch1064      resetRenderTimer();1065      flushSyncCallbacks();1066    }1067  }1068}1069export function pushRenderLanes(fiber: Fiber, lanes: Lanes) {1070  pushToStack(subtreeRenderLanesCursor, subtreeRenderLanes, fiber);1071  subtreeRenderLanes = mergeLanes(subtreeRenderLanes, lanes);1072  workInProgressRootIncludedLanes = mergeLanes(1073    workInProgressRootIncludedLanes,1074    lanes,1075  );1076}1077export function popRenderLanes(fiber: Fiber) {1078  subtreeRenderLanes = subtreeRenderLanesCursor.current;1079  popFromStack(subtreeRenderLanesCursor, fiber);1080}1081function prepareFreshStack(root: FiberRoot, lanes: Lanes) {1082  root.finishedWork = null;1083  root.finishedLanes = NoLanes;1084  const timeoutHandle = root.timeoutHandle;1085  if (timeoutHandle !== noTimeout) {1086    // The root previous suspended and scheduled a timeout to commit a fallback1087    // state. Now that we have additional work, cancel the timeout.1088    root.timeoutHandle = noTimeout;1089    // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above1090    cancelTimeout(timeoutHandle);1091  }1092  if (workInProgress !== null) {1093    let interruptedWork = workInProgress.return;1094    while (interruptedWork !== null) {1095      unwindInterruptedWork(interruptedWork, workInProgressRootRenderLanes);1096      interruptedWork = interruptedWork.return;1097    }1098  }1099  workInProgressRoot = root;1100  workInProgress = createWorkInProgress(root.current, null);1101  workInProgressRootRenderLanes = subtreeRenderLanes = workInProgressRootIncludedLanes = lanes;1102  workInProgressRootExitStatus = RootIncomplete;1103  workInProgressRootFatalError = null;1104  workInProgressRootSkippedLanes = NoLanes;1105  workInProgressRootUpdatedLanes = NoLanes;1106  workInProgressRootPingedLanes = NoLanes;1107  enqueueInterleavedUpdates();1108  if (__DEV__) {1109    ReactStrictModeWarnings.discardPendingWarnings();1110  }1111}1112function handleError(root, thrownValue): void {1113  do {1114    let erroredWork = workInProgress;1115    try {1116      // Reset module-level state that was set during the render phase.1117      resetContextDependencies();1118      resetHooksAfterThrow();1119      resetCurrentDebugFiberInDEV();1120      // TODO: I found and added this missing line while investigating a1121      // separate issue. Write a regression test using string refs.1122      ReactCurrentOwner.current = null;1123      if (erroredWork === null || erroredWork.return === null) {1124        // Expected to be working on a non-root fiber. This is a fatal error1125        // because there's no ancestor that can handle it; the root is1126        // supposed to capture all errors that weren't caught by an error1127        // boundary.1128        workInProgressRootExitStatus = RootFatalErrored;1129        workInProgressRootFatalError = thrownValue;1130        // Set `workInProgress` to null. This represents advancing to the next1131        // sibling, or the parent if there are no siblings. But since the root1132        // has no siblings nor a parent, we set it to null. Usually this is1133        // handled by `completeUnitOfWork` or `unwindWork`, but since we're1134        // intentionally not calling those, we need set it here.1135        // TODO: Consider calling `unwindWork` to pop the contexts.1136        workInProgress = null;1137        return;1138      }1139      if (enableProfilerTimer && erroredWork.mode & ProfileMode) {1140        // Record the time spent rendering before an error was thrown. This1141        // avoids inaccurate Profiler durations in the case of a1142        // suspended render.1143        stopProfilerTimerIfRunningAndRecordDelta(erroredWork, true);1144      }1145      throwException(1146        root,1147        erroredWork.return,1148        erroredWork,1149        thrownValue,1150        workInProgressRootRenderLanes,1151      );1152      completeUnitOfWork(erroredWork);1153    } catch (yetAnotherThrownValue) {1154      // Something in the return path also threw.1155      thrownValue = yetAnotherThrownValue;1156      if (workInProgress === erroredWork && erroredWork !== null) {1157        // If this boundary has already errored, then we had trouble processing1158        // the error. Bubble it to the next boundary.1159        erroredWork = erroredWork.return;1160        workInProgress = erroredWork;1161      } else {1162        erroredWork = workInProgress;1163      }1164      continue;1165    }1166    // Return to the normal work loop.1167    return;1168  } while (true);1169}1170function pushDispatcher() {1171  const prevDispatcher = ReactCurrentDispatcher.current;1172  ReactCurrentDispatcher.current = ContextOnlyDispatcher;1173  if (prevDispatcher === null) {1174    // The React isomorphic package does not include a default dispatcher.1175    // Instead the first renderer will lazily attach one, in order to give1176    // nicer error messages.1177    return ContextOnlyDispatcher;1178  } else {1179    return prevDispatcher;1180  }1181}1182function popDispatcher(prevDispatcher) {1183  ReactCurrentDispatcher.current = prevDispatcher;1184}1185export function markCommitTimeOfFallback() {1186  globalMostRecentFallbackTime = now();1187}1188export function markSkippedUpdateLanes(lane: Lane | Lanes): void {1189  workInProgressRootSkippedLanes = mergeLanes(1190    lane,1191    workInProgressRootSkippedLanes,1192  );1193}1194export function renderDidSuspend(): void {1195  if (workInProgressRootExitStatus === RootIncomplete) {1196    workInProgressRootExitStatus = RootSuspended;1197  }1198}1199export function renderDidSuspendDelayIfPossible(): void {1200  if (1201    workInProgressRootExitStatus === RootIncomplete ||1202    workInProgressRootExitStatus === RootSuspended1203  ) {1204    workInProgressRootExitStatus = RootSuspendedWithDelay;1205  }1206  // Check if there are updates that we skipped tree that might have unblocked1207  // this render.1208  if (1209    workInProgressRoot !== null &&1210    (includesNonIdleWork(workInProgressRootSkippedLanes) ||1211      includesNonIdleWork(workInProgressRootUpdatedLanes))1212  ) {1213    // Mark the current render as suspended so that we switch to working on1214    // the updates that were skipped. Usually we only suspend at the end of1215    // the render phase.1216    // TODO: We should probably always mark the root as suspended immediately1217    // (inside this function), since by suspending at the end of the render1218    // phase introduces a potential mistake where we suspend lanes that were1219    // pinged or updated while we were rendering.1220    markRootSuspended(workInProgressRoot, workInProgressRootRenderLanes);1221  }1222}1223export function renderDidError() {1224  if (workInProgressRootExitStatus !== RootCompleted) {1225    workInProgressRootExitStatus = RootErrored;1226  }1227}1228// Called during render to determine if anything has suspended.1229// Returns false if we're not sure.1230export function renderHasNotSuspendedYet(): boolean {1231  // If something errored or completed, we can't really be sure,1232  // so those are false.1233  return workInProgressRootExitStatus === RootIncomplete;1234}1235function renderRootSync(root: FiberRoot, lanes: Lanes) {1236  const prevExecutionContext = executionContext;1237  executionContext |= RenderContext;1238  const prevDispatcher = pushDispatcher();1239  // If the root or lanes have changed, throw out the existing stack1240  // and prepare a fresh one. Otherwise we'll continue where we left off.1241  if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) {1242    if (enableUpdaterTracking) {1243      if (isDevToolsPresent) {1244        const memoizedUpdaters = root.memoizedUpdaters;1245        if (memoizedUpdaters.size > 0) {1246          restorePendingUpdaters(root, workInProgressRootRenderLanes);1247          memoizedUpdaters.clear();1248        }1249        // At this point, move Fibers that scheduled the upcoming work from the Map to the Set.1250        // If we bailout on this work, we'll move them back (like above).1251        // It's important to move them now in case the work spawns more work at the same priority with different updaters.1252        // That way we can keep the current update and future updates separate.1253        movePendingFibersToMemoized(root, lanes);1254      }1255    }1256    prepareFreshStack(root, lanes);1257  }1258  if (__DEV__) {1259    if (enableDebugTracing) {1260      logRenderStarted(lanes);1261    }1262  }1263  if (enableSchedulingProfiler) {1264    markRenderStarted(lanes);1265  }1266  do {1267    try {1268      workLoopSync();1269      break;1270    } catch (thrownValue) {1271      handleError(root, thrownValue);1272    }1273  } while (true);1274  resetContextDependencies();1275  executionContext = prevExecutionContext;1276  popDispatcher(prevDispatcher);1277  if (workInProgress !== null) {1278    // This is a sync render, so we should have finished the whole tree.1279    invariant(1280      false,1281      'Cannot commit an incomplete root. This error is likely caused by a ' +1282        'bug in React. Please file an issue.',1283    );1284  }1285  if (__DEV__) {1286    if (enableDebugTracing) {1287      logRenderStopped();1288    }1289  }1290  if (enableSchedulingProfiler) {1291    markRenderStopped();1292  }1293  // Set this to null to indicate there's no in-progress render.1294  workInProgressRoot = null;1295  workInProgressRootRenderLanes = NoLanes;1296  return workInProgressRootExitStatus;1297}1298// The work loop is an extremely hot path. Tell Closure not to inline it.1299/** @noinline */1300function workLoopSync() {1301  // Already timed out, so perform work without checking if we need to yield.1302  while (workInProgress !== null) {1303    performUnitOfWork(workInProgress);1304  }1305}1306function renderRootConcurrent(root: FiberRoot, lanes: Lanes) {1307  const prevExecutionContext = executionContext;1308  executionContext |= RenderContext;1309  const prevDispatcher = pushDispatcher();1310  // If the root or lanes have changed, throw out the existing stack1311  // and prepare a fresh one. Otherwise we'll continue where we left off.1312  if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) {1313    if (enableUpdaterTracking) {1314      if (isDevToolsPresent) {1315        const memoizedUpdaters = root.memoizedUpdaters;1316        if (memoizedUpdaters.size > 0) {1317          restorePendingUpdaters(root, workInProgressRootRenderLanes);1318          memoizedUpdaters.clear();1319        }1320        // At this point, move Fibers that scheduled the upcoming work from the Map to the Set.1321        // If we bailout on this work, we'll move them back (like above).1322        // It's important to move them now in case the work spawns more work at the same priority with different updaters.1323        // That way we can keep the current update and future updates separate.1324        movePendingFibersToMemoized(root, lanes);1325      }1326    }1327    resetRenderTimer();1328    prepareFreshStack(root, lanes);1329  }1330  if (__DEV__) {1331    if (enableDebugTracing) {1332      logRenderStarted(lanes);1333    }1334  }1335  if (enableSchedulingProfiler) {1336    markRenderStarted(lanes);1337  }1338  do {1339    try {1340      workLoopConcurrent();1341      break;1342    } catch (thrownValue) {1343      handleError(root, thrownValue);1344    }1345  } while (true);1346  resetContextDependencies();1347  popDispatcher(prevDispatcher);1348  executionContext = prevExecutionContext;1349  if (__DEV__) {1350    if (enableDebugTracing) {1351      logRenderStopped();1352    }1353  }1354  // Check if the tree has completed.1355  if (workInProgress !== null) {1356    // Still work remaining.1357    if (enableSchedulingProfiler) {1358      markRenderYielded();1359    }1360    return RootIncomplete;1361  } else {1362    // Completed the tree.1363    if (enableSchedulingProfiler) {1364      markRenderStopped();1365    }1366    // Set this to null to indicate there's no in-progress render.1367    workInProgressRoot = null;1368    workInProgressRootRenderLanes = NoLanes;1369    // Return the final exit status.1370    return workInProgressRootExitStatus;1371  }1372}1373/** @noinline */1374function workLoopConcurrent() {1375  // Perform work until Scheduler asks us to yield1376  while (workInProgress !== null && !shouldYield()) {1377    performUnitOfWork(workInProgress);1378  }1379}1380function performUnitOfWork(unitOfWork: Fiber): void {1381  // The current, flushed, state of this fiber is the alternate. Ideally1382  // nothing should rely on this, but relying on it here means that we don't1383  // need an additional field on the work in progress.1384  const current = unitOfWork.alternate;1385  setCurrentDebugFiberInDEV(unitOfWork);1386  let next;1387  if (enableProfilerTimer && (unitOfWork.mode & ProfileMode) !== NoMode) {1388    startProfilerTimer(unitOfWork);1389    next = beginWork(current, unitOfWork, subtreeRenderLanes);1390    stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true);1391  } else {1392    next = beginWork(current, unitOfWork, subtreeRenderLanes);1393  }1394  resetCurrentDebugFiberInDEV();1395  unitOfWork.memoizedProps = unitOfWork.pendingProps;1396  if (next === null) {1397    // If this doesn't spawn new work, complete the current work.1398    completeUnitOfWork(unitOfWork);1399  } else {1400    workInProgress = next;1401  }1402  ReactCurrentOwner.current = null;1403}1404function completeUnitOfWork(unitOfWork: Fiber): void {1405  // Attempt to complete the current unit of work, then move to the next1406  // sibling. If there are no more siblings, return to the parent fiber.1407  let completedWork = unitOfWork;1408  do {1409    // The current, flushed, state of this fiber is the alternate. Ideally1410    // nothing should rely on this, but relying on it here means that we don't1411    // need an additional field on the work in progress.1412    const current = completedWork.alternate;1413    const returnFiber = completedWork.return;1414    // Check if the work completed or if something threw.1415    if ((completedWork.flags & Incomplete) === NoFlags) {1416      setCurrentDebugFiberInDEV(completedWork);1417      let next;1418      if (1419        !enableProfilerTimer ||1420        (completedWork.mode & ProfileMode) === NoMode1421      ) {1422        next = completeWork(current, completedWork, subtreeRenderLanes);1423      } else {1424        startProfilerTimer(completedWork);1425        next = completeWork(current, completedWork, subtreeRenderLanes);1426        // Update render duration assuming we didn't error.1427        stopProfilerTimerIfRunningAndRecordDelta(completedWork, false);1428      }1429      resetCurrentDebugFiberInDEV();1430      if (next !== null) {1431        // Completing this fiber spawned new work. Work on that next.1432        workInProgress = next;1433        return;1434      }1435    } else {1436      // This fiber did not complete because something threw. Pop values off1437      // the stack without entering the complete phase. If this is a boundary,1438      // capture values if possible.1439      const next = unwindWork(completedWork, subtreeRenderLanes);1440      // Because this fiber did not complete, don't reset its lanes.1441      if (next !== null) {1442        // If completing this work spawned new work, do that next. We'll come1443        // back here again.1444        // Since we're restarting, remove anything that is not a host effect1445        // from the effect tag.1446        next.flags &= HostEffectMask;1447        workInProgress = next;1448        return;1449      }1450      if (1451        enableProfilerTimer &&1452        (completedWork.mode & ProfileMode) !== NoMode1453      ) {1454        // Record the render duration for the fiber that errored.1455        stopProfilerTimerIfRunningAndRecordDelta(completedWork, false);1456        // Include the time spent working on failed children before continuing.1457        let actualDuration = completedWork.actualDuration;1458        let child = completedWork.child;1459        while (child !== null) {1460          actualDuration += child.actualDuration;1461          child = child.sibling;1462        }1463        completedWork.actualDuration = actualDuration;1464      }1465      if (returnFiber !== null) {1466        // Mark the parent fiber as incomplete and clear its subtree flags.1467        returnFiber.flags |= Incomplete;1468        returnFiber.subtreeFlags = NoFlags;1469        returnFiber.deletions = null;1470      }1471    }1472    const siblingFiber = completedWork.sibling;1473    if (siblingFiber !== null) {1474      // If there is more work to do in this returnFiber, do that next.1475      workInProgress = siblingFiber;1476      return;1477    }1478    // Otherwise, return to the parent1479    completedWork = returnFiber;1480    // Update the next thing we're working on in case something throws.1481    workInProgress = completedWork;1482  } while (completedWork !== null);1483  // We've reached the root.1484  if (workInProgressRootExitStatus === RootIncomplete) {1485    workInProgressRootExitStatus = RootCompleted;1486  }1487}1488function commitRoot(root) {1489  // TODO: This no longer makes any sense. We already wrap the mutation and1490  // layout phases. Should be able to remove.1491  const previousUpdateLanePriority = getCurrentUpdatePriority();1492  const prevTransition = ReactCurrentBatchConfig.transition;1493  try {1494    ReactCurrentBatchConfig.transition = 0;1495    setCurrentUpdatePriority(DiscreteEventPriority);1496    commitRootImpl(root, previousUpdateLanePriority);1497  } finally {1498    ReactCurrentBatchConfig.transition = prevTransition;1499    setCurrentUpdatePriority(previousUpdateLanePriority);1500  }1501  return null;1502}1503function commitRootImpl(root, renderPriorityLevel) {1504  do {1505    // `flushPassiveEffects` will call `flushSyncUpdateQueue` at the end, which1506    // means `flushPassiveEffects` will sometimes result in additional1507    // passive effects. So we need to keep flushing in a loop until there are1508    // no more pending effects.1509    // TODO: Might be better if `flushPassiveEffects` did not automatically1510    // flush synchronous work at the end, to avoid factoring hazards like this.1511    flushPassiveEffects();1512  } while (rootWithPendingPassiveEffects !== null);1513  flushRenderPhaseStrictModeWarningsInDEV();1514  invariant(1515    (executionContext & (RenderContext | CommitContext)) === NoContext,1516    'Should not already be working.',1517  );1518  const finishedWork = root.finishedWork;1519  const lanes = root.finishedLanes;1520  if (__DEV__) {1521    if (enableDebugTracing) {1522      logCommitStarted(lanes);1523    }1524  }1525  if (enableSchedulingProfiler) {1526    markCommitStarted(lanes);1527  }1528  if (finishedWork === null) {1529    if (__DEV__) {1530      if (enableDebugTracing) {1531        logCommitStopped();1532      }1533    }1534    if (enableSchedulingProfiler) {1535      markCommitStopped();1536    }1537    return null;1538  } else {1539    if (__DEV__) {1540      if (lanes === NoLanes) {1541        console.error(1542          'root.finishedLanes should not be empty during a commit. This is a ' +1543            'bug in React.',1544        );1545      }1546    }1547  }1548  root.finishedWork = null;1549  root.finishedLanes = NoLanes;1550  invariant(1551    finishedWork !== root.current,1552    'Cannot commit the same tree as before. This error is likely caused by ' +1553      'a bug in React. Please file an issue.',1554  );1555  // commitRoot never returns a continuation; it always finishes synchronously.1556  // So we can clear these now to allow a new callback to be scheduled.1557  root.callbackNode = null;1558  root.callbackPriority = NoLane;1559  // Update the first and last pending times on this root. The new first1560  // pending time is whatever is left on the root fiber.1561  let remainingLanes = mergeLanes(finishedWork.lanes, finishedWork.childLanes);1562  markRootFinished(root, remainingLanes);1563  if (root === workInProgressRoot) {1564    // We can reset these now that they are finished.1565    workInProgressRoot = null;1566    workInProgress = null;1567    workInProgressRootRenderLanes = NoLanes;1568  } else {1569    // This indicates that the last root we worked on is not the same one that1570    // we're committing now. This most commonly happens when a suspended root1571    // times out.1572  }1573  // If there are pending passive effects, schedule a callback to process them.1574  // Do this as early as possible, so it is queued before anything else that1575  // might get scheduled in the commit phase. (See #16714.)1576  // TODO: Delete all other places that schedule the passive effect callback1577  // They're redundant.1578  if (1579    (finishedWork.subtreeFlags & PassiveMask) !== NoFlags ||1580    (finishedWork.flags & PassiveMask) !== NoFlags1581  ) {1582    if (!rootDoesHavePassiveEffects) {1583      rootDoesHavePassiveEffects = true;1584      scheduleCallback(NormalSchedulerPriority, () => {1585        flushPassiveEffects();1586        return null;1587      });1588    }1589  }1590  // Check if there are any effects in the whole tree.1591  // TODO: This is left over from the effect list implementation, where we had1592  // to check for the existence of `firstEffect` to satisfy Flow. I think the1593  // only other reason this optimization exists is because it affects profiling.1594  // Reconsider whether this is necessary.1595  const subtreeHasEffects =1596    (finishedWork.subtreeFlags &1597      (BeforeMutationMask | MutationMask | LayoutMask | PassiveMask)) !==1598    NoFlags;1599  const rootHasEffect =1600    (finishedWork.flags &1601      (BeforeMutationMask | MutationMask | LayoutMask | PassiveMask)) !==1602    NoFlags;1603  if (subtreeHasEffects || rootHasEffect) {1604    const prevTransition = ReactCurrentBatchConfig.transition;1605    ReactCurrentBatchConfig.transition = 0;1606    const previousPriority = getCurrentUpdatePriority();1607    setCurrentUpdatePriority(DiscreteEventPriority);1608    const prevExecutionContext = executionContext;1609    executionContext |= CommitContext;1610    // Reset this to null before calling lifecycles1611    ReactCurrentOwner.current = null;1612    // The commit phase is broken into several sub-phases. We do a separate pass1613    // of the effect list for each phase: all mutation effects come before all1614    // layout effects, and so on.1615    // The first phase a "before mutation" phase. We use this phase to read the1616    // state of the host tree right before we mutate it. This is where1617    // getSnapshotBeforeUpdate is called.1618    const shouldFireAfterActiveInstanceBlur = commitBeforeMutationEffects(1619      root,1620      finishedWork,1621    );1622    if (enableProfilerTimer) {1623      // Mark the current commit time to be shared by all Profilers in this1624      // batch. This enables them to be grouped later.1625      recordCommitTime();1626    }1627    if (enableProfilerTimer && enableProfilerNestedUpdateScheduledHook) {1628      // Track the root here, rather than in commitLayoutEffects(), because of ref setters.1629      // Updates scheduled during ref detachment should also be flagged.1630      rootCommittingMutationOrLayoutEffects = root;1631    }1632    // The next phase is the mutation phase, where we mutate the host tree.1633    commitMutationEffects(root, finishedWork, lanes);1634    if (enableCreateEventHandleAPI) {1635      if (shouldFireAfterActiveInstanceBlur) {1636        afterActiveInstanceBlur();1637      }1638    }1639    resetAfterCommit(root.containerInfo);1640    // The work-in-progress tree is now the current tree. This must come after1641    // the mutation phase, so that the previous tree is still current during1642    // componentWillUnmount, but before the layout phase, so that the finished1643    // work is current during componentDidMount/Update.1644    root.current = finishedWork;1645    // The next phase is the layout phase, where we call effects that read1646    // the host tree after it's been mutated. The idiomatic use case for this is1647    // layout, but class component lifecycles also fire here for legacy reasons.1648    if (__DEV__) {1649      if (enableDebugTracing) {1650        logLayoutEffectsStarted(lanes);1651      }1652    }1653    if (enableSchedulingProfiler) {1654      markLayoutEffectsStarted(lanes);1655    }1656    commitLayoutEffects(finishedWork, root, lanes);1657    if (__DEV__) {1658      if (enableDebugTracing) {1659        logLayoutEffectsStopped();1660      }1661    }1662    if (enableSchedulingProfiler) {1663      markLayoutEffectsStopped();1664    }1665    if (enableProfilerTimer && enableProfilerNestedUpdateScheduledHook) {1666      rootCommittingMutationOrLayoutEffects = null;1667    }1668    // Tell Scheduler to yield at the end of the frame, so the browser has an1669    // opportunity to paint.1670    requestPaint();1671    executionContext = prevExecutionContext;1672    // Reset the priority to the previous non-sync value.1673    setCurrentUpdatePriority(previousPriority);1674    ReactCurrentBatchConfig.transition = prevTransition;1675  } else {1676    // No effects.1677    root.current = finishedWork;1678    // Measure these anyway so the flamegraph explicitly shows that there were1679    // no effects.1680    // TODO: Maybe there's a better way to report this.1681    if (enableProfilerTimer) {1682      recordCommitTime();1683    }1684  }1685  const rootDidHavePassiveEffects = rootDoesHavePassiveEffects;1686  if (rootDoesHavePassiveEffects) {1687    // This commit has passive effects. Stash a reference to them. But don't1688    // schedule a callback until after flushing layout work.1689    rootDoesHavePassiveEffects = false;1690    rootWithPendingPassiveEffects = root;1691    pendingPassiveEffectsLanes = lanes;1692  }1693  // Read this again, since an effect might have updated it1694  remainingLanes = root.pendingLanes;1695  // Check if there's remaining work on this root1696  if (remainingLanes === NoLanes) {1697    // If there's no remaining work, we can clear the set of already failed1698    // error boundaries.1699    legacyErrorBoundariesThatAlreadyFailed = null;1700  }1701  if (__DEV__ && enableStrictEffects) {1702    if (!rootDidHavePassiveEffects) {1703      commitDoubleInvokeEffectsInDEV(root.current, false);1704    }1705  }1706  if (includesSomeLane(remainingLanes, (SyncLane: Lane))) {1707    if (enableProfilerTimer && enableProfilerNestedUpdatePhase) {1708      markNestedUpdateScheduled();1709    }1710    // Count the number of times the root synchronously re-renders without1711    // finishing. If there are too many, it indicates an infinite update loop.1712    if (root === rootWithNestedUpdates) {1713      nestedUpdateCount++;1714    } else {1715      nestedUpdateCount = 0;1716      rootWithNestedUpdates = root;1717    }1718  } else {1719    nestedUpdateCount = 0;1720  }1721  onCommitRootDevTools(finishedWork.stateNode, renderPriorityLevel);1722  if (enableUpdaterTracking) {1723    if (isDevToolsPresent) {1724      root.memoizedUpdaters.clear();1725    }1726  }1727  if (__DEV__) {1728    onCommitRootTestSelector();1729  }1730  // Always call this before exiting `commitRoot`, to ensure that any1731  // additional work on this root is scheduled.1732  ensureRootIsScheduled(root, now());1733  if (hasUncaughtError) {1734    hasUncaughtError = false;1735    const error = firstUncaughtError;1736    firstUncaughtError = null;1737    throw error;1738  }1739  // If the passive effects are the result of a discrete render, flush them1740  // synchronously at the end of the current task so that the result is1741  // immediately observable. Otherwise, we assume that they are not1742  // order-dependent and do not need to be observed by external systems, so we1743  // can wait until after paint.1744  // TODO: We can optimize this by not scheduling the callback earlier. Since we1745  // currently schedule the callback in multiple places, will wait until those1746  // are consolidated.1747  if (1748    includesSomeLane(pendingPassiveEffectsLanes, SyncLane) &&1749    root.tag !== LegacyRoot1750  ) {1751    flushPassiveEffects();1752  }1753  // If layout work was scheduled, flush it now.1754  flushSyncCallbacks();1755  if (__DEV__) {1756    if (enableDebugTracing) {1757      logCommitStopped();1758    }1759  }1760  if (enableSchedulingProfiler) {1761    markCommitStopped();1762  }1763  return null;1764}1765export function flushPassiveEffects(): boolean {1766  // Returns whether passive effects were flushed.1767  // TODO: Combine this check with the one in flushPassiveEFfectsImpl. We should1768  // probably just combine the two functions. I believe they were only separate1769  // in the first place because we used to wrap it with1770  // `Scheduler.runWithPriority`, which accepts a function. But now we track the1771  // priority within React itself, so we can mutate the variable directly.1772  if (rootWithPendingPassiveEffects !== null) {1773    const renderPriority = lanesToEventPriority(pendingPassiveEffectsLanes);1774    const priority = lowerEventPriority(DefaultEventPriority, renderPriority);1775    const prevTransition = ReactCurrentBatchConfig.transition;1776    const previousPriority = getCurrentUpdatePriority();1777    try {1778      ReactCurrentBatchConfig.transition = 0;1779      setCurrentUpdatePriority(priority);1780      return flushPassiveEffectsImpl();1781    } finally {1782      setCurrentUpdatePriority(previousPriority);1783      ReactCurrentBatchConfig.transition = prevTransition;1784    }1785  }1786  return false;1787}1788export function enqueuePendingPassiveProfilerEffect(fiber: Fiber): void {1789  if (enableProfilerTimer && enableProfilerCommitHooks) {1790    pendingPassiveProfilerEffects.push(fiber);1791    if (!rootDoesHavePassiveEffects) {1792      rootDoesHavePassiveEffects = true;1793      scheduleCallback(NormalSchedulerPriority, () => {1794        flushPassiveEffects();1795        return null;1796      });1797    }1798  }1799}1800function flushPassiveEffectsImpl() {1801  if (rootWithPendingPassiveEffects === null) {1802    return false;1803  }1804  const root = rootWithPendingPassiveEffects;1805  const lanes = pendingPassiveEffectsLanes;1806  rootWithPendingPassiveEffects = null;1807  // TODO: This is sometimes out of sync with rootWithPendingPassiveEffects.1808  // Figure out why and fix it. It's not causing any known issues (probably1809  // because it's only used for profiling), but it's a refactor hazard.1810  pendingPassiveEffectsLanes = NoLanes;1811  invariant(1812    (executionContext & (RenderContext | CommitContext)) === NoContext,1813    'Cannot flush passive effects while already rendering.',1814  );1815  if (__DEV__) {1816    if (enableDebugTracing) {1817      logPassiveEffectsStarted(lanes);1818    }1819  }1820  if (enableSchedulingProfiler) {1821    markPassiveEffectsStarted(lanes);1822  }1823  const prevExecutionContext = executionContext;1824  executionContext |= CommitContext;1825  commitPassiveUnmountEffects(root.current);1826  commitPassiveMountEffects(root, root.current);1827  // TODO: Move to commitPassiveMountEffects1828  if (enableProfilerTimer && enableProfilerCommitHooks) {1829    const profilerEffects = pendingPassiveProfilerEffects;1830    pendingPassiveProfilerEffects = [];1831    for (let i = 0; i < profilerEffects.length; i++) {1832      const fiber = ((profilerEffects[i]: any): Fiber);1833      commitPassiveEffectDurations(root, fiber);1834    }1835  }1836  if (__DEV__) {1837    if (enableDebugTracing) {1838      logPassiveEffectsStopped();1839    }1840  }1841  if (enableSchedulingProfiler) {1842    markPassiveEffectsStopped();1843  }1844  if (__DEV__ && enableStrictEffects) {1845    commitDoubleInvokeEffectsInDEV(root.current, true);1846  }1847  executionContext = prevExecutionContext;1848  flushSyncCallbacks();1849  // If additional passive effects were scheduled, increment a counter. If this1850  // exceeds the limit, we'll fire a warning.1851  nestedPassiveUpdateCount =1852    rootWithPendingPassiveEffects === null ? 0 : nestedPassiveUpdateCount + 1;1853  // TODO: Move to commitPassiveMountEffects1854  onPostCommitRootDevTools(root);1855  if (enableProfilerTimer && enableProfilerCommitHooks) {1856    const stateNode = root.current.stateNode;1857    stateNode.effectDuration = 0;1858    stateNode.passiveEffectDuration = 0;1859  }1860  return true;1861}1862export function isAlreadyFailedLegacyErrorBoundary(instance: mixed): boolean {1863  return (1864    legacyErrorBoundariesThatAlreadyFailed !== null &&1865    legacyErrorBoundariesThatAlreadyFailed.has(instance)1866  );1867}1868export function markLegacyErrorBoundaryAsFailed(instance: mixed) {1869  if (legacyErrorBoundariesThatAlreadyFailed === null) {1870    legacyErrorBoundariesThatAlreadyFailed = new Set([instance]);1871  } else {1872    legacyErrorBoundariesThatAlreadyFailed.add(instance);1873  }1874}1875function prepareToThrowUncaughtError(error: mixed) {1876  if (!hasUncaughtError) {1877    hasUncaughtError = true;1878    firstUncaughtError = error;1879  }1880}1881export const onUncaughtError = prepareToThrowUncaughtError;1882function captureCommitPhaseErrorOnRoot(1883  rootFiber: Fiber,1884  sourceFiber: Fiber,1885  error: mixed,1886) {1887  const errorInfo = createCapturedValue(error, sourceFiber);1888  const update = createRootErrorUpdate(rootFiber, errorInfo, (SyncLane: Lane));1889  enqueueUpdate(rootFiber, update, (SyncLane: Lane));1890  const eventTime = requestEventTime();1891  const root = markUpdateLaneFromFiberToRoot(rootFiber, (SyncLane: Lane));1892  if (root !== null) {1893    markRootUpdated(root, SyncLane, eventTime);1894    ensureRootIsScheduled(root, eventTime);1895  }1896}1897export function captureCommitPhaseError(1898  sourceFiber: Fiber,1899  nearestMountedAncestor: Fiber | null,1900  error: mixed,1901) {1902  if (sourceFiber.tag === HostRoot) {1903    // Error was thrown at the root. There is no parent, so the root1904    // itself should capture it.1905    captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error);1906    return;1907  }1908  let fiber = null;1909  if (skipUnmountedBoundaries) {1910    fiber = nearestMountedAncestor;1911  } else {1912    fiber = sourceFiber.return;1913  }1914  while (fiber !== null) {1915    if (fiber.tag === HostRoot) {1916      captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error);1917      return;1918    } else if (fiber.tag === ClassComponent) {1919      const ctor = fiber.type;1920      const instance = fiber.stateNode;1921      if (1922        typeof ctor.getDerivedStateFromError === 'function' ||1923        (typeof instance.componentDidCatch === 'function' &&1924          !isAlreadyFailedLegacyErrorBoundary(instance))1925      ) {1926        const errorInfo = createCapturedValue(error, sourceFiber);1927        const update = createClassErrorUpdate(1928          fiber,1929          errorInfo,1930          (SyncLane: Lane),1931        );1932        enqueueUpdate(fiber, update, (SyncLane: Lane));1933        const eventTime = requestEventTime();1934        const root = markUpdateLaneFromFiberToRoot(fiber, (SyncLane: Lane));1935        if (root !== null) {1936          markRootUpdated(root, SyncLane, eventTime);1937          ensureRootIsScheduled(root, eventTime);1938        }1939        return;1940      }1941    }1942    fiber = fiber.return;1943  }1944  if (__DEV__) {1945    // TODO: Until we re-land skipUnmountedBoundaries (see #20147), this warning1946    // will fire for errors that are thrown by destroy functions inside deleted1947    // trees. What it should instead do is propagate the error to the parent of1948    // the deleted tree. In the meantime, do not add this warning to the1949    // allowlist; this is only for our internal use.1950    console.error(1951      'Internal React error: Attempted to capture a commit phase error ' +1952        'inside a detached tree. This indicates a bug in React. Likely ' +1953        'causes include deleting the same fiber more than once, committing an ' +1954        'already-finished tree, or an inconsistent return pointer.\n\n' +1955        'Error message:\n\n%s',1956      error,1957    );1958  }1959}1960export function pingSuspendedRoot(1961  root: FiberRoot,1962  wakeable: Wakeable,1963  pingedLanes: Lanes,1964) {1965  const pingCache = root.pingCache;1966  if (pingCache !== null) {1967    // The wakeable resolved, so we no longer need to memoize, because it will1968    // never be thrown again.1969    pingCache.delete(wakeable);1970  }1971  const eventTime = requestEventTime();1972  markRootPinged(root, pingedLanes, eventTime);1973  if (1974    workInProgressRoot === root &&1975    isSubsetOfLanes(workInProgressRootRenderLanes, pingedLanes)1976  ) {1977    // Received a ping at the same priority level at which we're currently1978    // rendering. We might want to restart this render. This should mirror1979    // the logic of whether or not a root suspends once it completes.1980    // TODO: If we're rendering sync either due to Sync, Batched or expired,1981    // we should probably never restart.1982    // If we're suspended with delay, or if it's a retry, we'll always suspend1983    // so we can always restart.1984    if (1985      workInProgressRootExitStatus === RootSuspendedWithDelay ||1986      (workInProgressRootExitStatus === RootSuspended &&1987        includesOnlyRetries(workInProgressRootRenderLanes) &&1988        now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS)1989    ) {1990      // Restart from the root.1991      prepareFreshStack(root, NoLanes);1992    } else {1993      // Even though we can't restart right now, we might get an1994      // opportunity later. So we mark this render as having a ping.1995      workInProgressRootPingedLanes = mergeLanes(1996        workInProgressRootPingedLanes,1997        pingedLanes,1998      );1999    }2000  }2001  ensureRootIsScheduled(root, eventTime);2002}2003function retryTimedOutBoundary(boundaryFiber: Fiber, retryLane: Lane) {2004  // The boundary fiber (a Suspense component or SuspenseList component)2005  // previously was rendered in its fallback state. One of the promises that2006  // suspended it has resolved, which means at least part of the tree was2007  // likely unblocked. Try rendering again, at a new lanes.2008  if (retryLane === NoLane) {2009    // TODO: Assign this to `suspenseState.retryLane`? to avoid2010    // unnecessary entanglement?2011    retryLane = requestRetryLane(boundaryFiber);2012  }2013  // TODO: Special case idle priority?2014  const eventTime = requestEventTime();2015  const root = markUpdateLaneFromFiberToRoot(boundaryFiber, retryLane);2016  if (root !== null) {2017    markRootUpdated(root, retryLane, eventTime);2018    ensureRootIsScheduled(root, eventTime);2019  }2020}2021export function retryDehydratedSuspenseBoundary(boundaryFiber: Fiber) {2022  const suspenseState: null | SuspenseState = boundaryFiber.memoizedState;2023  let retryLane = NoLane;2024  if (suspenseState !== null) {2025    retryLane = suspenseState.retryLane;2026  }2027  retryTimedOutBoundary(boundaryFiber, retryLane);2028}2029export function resolveRetryWakeable(boundaryFiber: Fiber, wakeable: Wakeable) {2030  let retryLane = NoLane; // Default2031  let retryCache: WeakSet<Wakeable> | Set<Wakeable> | null;2032  if (enableSuspenseServerRenderer) {2033    switch (boundaryFiber.tag) {2034      case SuspenseComponent:2035        retryCache = boundaryFiber.stateNode;2036        const suspenseState: null | SuspenseState = boundaryFiber.memoizedState;2037        if (suspenseState !== null) {2038          retryLane = suspenseState.retryLane;2039        }2040        break;2041      case SuspenseListComponent:2042        retryCache = boundaryFiber.stateNode;2043        break;2044      default:2045        invariant(2046          false,2047          'Pinged unknown suspense boundary type. ' +2048            'This is probably a bug in React.',2049        );2050    }2051  } else {2052    retryCache = boundaryFiber.stateNode;2053  }2054  if (retryCache !== null) {2055    // The wakeable resolved, so we no longer need to memoize, because it will2056    // never be thrown again.2057    retryCache.delete(wakeable);2058  }2059  retryTimedOutBoundary(boundaryFiber, retryLane);2060}2061// Computes the next Just Noticeable Difference (JND) boundary.2062// The theory is that a person can't tell the difference between small differences in time.2063// Therefore, if we wait a bit longer than necessary that won't translate to a noticeable2064// difference in the experience. However, waiting for longer might mean that we can avoid2065// showing an intermediate loading state. The longer we have already waited, the harder it2066// is to tell small differences in time. Therefore, the longer we've already waited,2067// the longer we can wait additionally. At some point we have to give up though.2068// We pick a train model where the next boundary commits at a consistent schedule.2069// These particular numbers are vague estimates. We expect to adjust them based on research.2070function jnd(timeElapsed: number) {2071  return timeElapsed < 1202072    ? 1202073    : timeElapsed < 4802074    ? 4802075    : timeElapsed < 10802076    ? 10802077    : timeElapsed < 19202078    ? 19202079    : timeElapsed < 30002080    ? 30002081    : timeElapsed < 43202082    ? 43202083    : ceil(timeElapsed / 1960) * 1960;2084}2085function checkForNestedUpdates() {2086  if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {2087    nestedUpdateCount = 0;2088    rootWithNestedUpdates = null;2089    invariant(2090      false,2091      'Maximum update depth exceeded. This can happen when a component ' +2092        'repeatedly calls setState inside componentWillUpdate or ' +2093        'componentDidUpdate. React limits the number of nested updates to ' +2094        'prevent infinite loops.',2095    );2096  }2097  if (__DEV__) {2098    if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) {2099      nestedPassiveUpdateCount = 0;2100      console.error(2101        'Maximum update depth exceeded. This can happen when a component ' +2102          "calls setState inside useEffect, but useEffect either doesn't " +2103          'have a dependency array, or one of the dependencies changes on ' +2104          'every render.',2105      );2106    }2107  }2108}2109function flushRenderPhaseStrictModeWarningsInDEV() {2110  if (__DEV__) {2111    ReactStrictModeWarnings.flushLegacyContextWarning();2112    if (warnAboutDeprecatedLifecycles) {2113      ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings();2114    }2115  }2116}2117function commitDoubleInvokeEffectsInDEV(2118  fiber: Fiber,2119  hasPassiveEffects: boolean,2120) {2121  if (__DEV__ && enableStrictEffects) {2122    // TODO (StrictEffects) Should we set a marker on the root if it contains strict effects2123    // so we don't traverse unnecessarily? similar to subtreeFlags but just at the root level.2124    // Maybe not a big deal since this is DEV only behavior.2125    setCurrentDebugFiberInDEV(fiber);2126    invokeEffectsInDev(fiber, MountLayoutDev, invokeLayoutEffectUnmountInDEV);2127    if (hasPassiveEffects) {2128      invokeEffectsInDev(2129        fiber,2130        MountPassiveDev,2131        invokePassiveEffectUnmountInDEV,2132      );2133    }2134    invokeEffectsInDev(fiber, MountLayoutDev, invokeLayoutEffectMountInDEV);2135    if (hasPassiveEffects) {2136      invokeEffectsInDev(fiber, MountPassiveDev, invokePassiveEffectMountInDEV);2137    }2138    resetCurrentDebugFiberInDEV();2139  }2140}2141function invokeEffectsInDev(2142  firstChild: Fiber,2143  fiberFlags: Flags,2144  invokeEffectFn: (fiber: Fiber) => void,2145): void {2146  if (__DEV__ && enableStrictEffects) {2147    // We don't need to re-check StrictEffectsMode here.2148    // This function is only called if that check has already passed.2149    let current = firstChild;2150    let subtreeRoot = null;2151    while (current !== null) {2152      const primarySubtreeFlag = current.subtreeFlags & fiberFlags;2153      if (2154        current !== subtreeRoot &&2155        current.child !== null &&2156        primarySubtreeFlag !== NoFlags2157      ) {2158        current = current.child;2159      } else {2160        if ((current.flags & fiberFlags) !== NoFlags) {2161          invokeEffectFn(current);2162        }2163        if (current.sibling !== null) {2164          current = current.sibling;2165        } else {2166          current = subtreeRoot = current.return;2167        }2168      }2169    }2170  }2171}2172let didWarnStateUpdateForNotYetMountedComponent: Set<string> | null = null;2173function warnAboutUpdateOnNotYetMountedFiberInDEV(fiber) {2174  if (__DEV__) {2175    if ((executionContext & RenderContext) !== NoContext) {2176      // We let the other warning about render phase updates deal with this one.2177      return;2178    }2179    if (!(fiber.mode & ConcurrentMode)) {2180      return;2181    }2182    const tag = fiber.tag;2183    if (2184      tag !== IndeterminateComponent &&2185      tag !== HostRoot &&2186      tag !== ClassComponent &&2187      tag !== FunctionComponent &&2188      tag !== ForwardRef &&2189      tag !== MemoComponent &&2190      tag !== SimpleMemoComponent2191    ) {2192      // Only warn for user-defined components, not internal ones like Suspense.2193      return;2194    }2195    // We show the whole stack but dedupe on the top component's name because2196    // the problematic code almost always lies inside that component.2197    const componentName = getComponentNameFromFiber(fiber) || 'ReactComponent';2198    if (didWarnStateUpdateForNotYetMountedComponent !== null) {2199      if (didWarnStateUpdateForNotYetMountedComponent.has(componentName)) {2200        return;2201      }2202      didWarnStateUpdateForNotYetMountedComponent.add(componentName);2203    } else {2204      didWarnStateUpdateForNotYetMountedComponent = new Set([componentName]);2205    }2206    const previousFiber = ReactCurrentFiberCurrent;2207    try {2208      setCurrentDebugFiberInDEV(fiber);2209      console.error(2210        "Can't perform a React state update on a component that hasn't mounted yet. " +2211          'This indicates that you have a side-effect in your render function that ' +2212          'asynchronously later calls tries to update the component. Move this work to ' +2213          'useEffect instead.',2214      );2215    } finally {2216      if (previousFiber) {2217        setCurrentDebugFiberInDEV(fiber);2218      } else {2219        resetCurrentDebugFiberInDEV();2220      }2221    }2222  }2223}2224let beginWork;2225if (__DEV__ && replayFailedUnitOfWorkWithInvokeGuardedCallback) {2226  const dummyFiber = null;2227  beginWork = (current, unitOfWork, lanes) => {2228    // If a component throws an error, we replay it again in a synchronously2229    // dispatched event, so that the debugger will treat it as an uncaught2230    // error See ReactErrorUtils for more information.2231    // Before entering the begin phase, copy the work-in-progress onto a dummy2232    // fiber. If beginWork throws, we'll use this to reset the state.2233    const originalWorkInProgressCopy = assignFiberPropertiesInDEV(2234      dummyFiber,2235      unitOfWork,2236    );2237    try {2238      return originalBeginWork(current, unitOfWork, lanes);2239    } catch (originalError) {2240      if (2241        originalError !== null &&2242        typeof originalError === 'object' &&2243        typeof originalError.then === 'function'2244      ) {2245        // Don't replay promises. Treat everything else like an error.2246        throw originalError;2247      }2248      // Keep this code in sync with handleError; any changes here must have2249      // corresponding changes there.2250      resetContextDependencies();2251      resetHooksAfterThrow();2252      // Don't reset current debug fiber, since we're about to work on the2253      // same fiber again.2254      // Unwind the failed stack frame2255      unwindInterruptedWork(unitOfWork, workInProgressRootRenderLanes);2256      // Restore the original properties of the fiber.2257      assignFiberPropertiesInDEV(unitOfWork, originalWorkInProgressCopy);2258      if (enableProfilerTimer && unitOfWork.mode & ProfileMode) {2259        // Reset the profiler timer.2260        startProfilerTimer(unitOfWork);2261      }2262      // Run beginWork again.2263      invokeGuardedCallback(2264        null,2265        originalBeginWork,2266        null,2267        current,2268        unitOfWork,2269        lanes,2270      );2271      if (hasCaughtError()) {2272        const replayError = clearCaughtError();2273        if (2274          typeof replayError === 'object' &&2275          replayError !== null &&2276          replayError._suppressLogging &&2277          typeof originalError === 'object' &&2278          originalError !== null &&2279          !originalError._suppressLogging2280        ) {2281          // If suppressed, let the flag carry over to the original error which is the one we'll rethrow.2282          originalError._suppressLogging = true;2283        }2284      }2285      // We always throw the original error in case the second render pass is not idempotent.2286      // This can happen if a memoized function or CommonJS module doesn't throw after first invokation.2287      throw originalError;2288    }2289  };2290} else {2291  beginWork = originalBeginWork;2292}2293let didWarnAboutUpdateInRender = false;2294let didWarnAboutUpdateInRenderForAnotherComponent;2295if (__DEV__) {2296  didWarnAboutUpdateInRenderForAnotherComponent = new Set();2297}2298function warnAboutRenderPhaseUpdatesInDEV(fiber) {2299  if (__DEV__) {2300    if (2301      ReactCurrentDebugFiberIsRenderingInDEV &&2302      (executionContext & RenderContext) !== NoContext &&2303      !getIsUpdatingOpaqueValueInRenderPhaseInDEV()2304    ) {2305      switch (fiber.tag) {2306        case FunctionComponent:2307        case ForwardRef:2308        case SimpleMemoComponent: {2309          const renderingComponentName =2310            (workInProgress && getComponentNameFromFiber(workInProgress)) ||2311            'Unknown';2312          // Dedupe by the rendering component because it's the one that needs to be fixed....ReactFiberWorkLoop.js
Source:ReactFiberWorkLoop.js  
...212  return lane;213}214export function scheduleUpdateOnFiber(fiber, lane, eventTime) {215  // checkForNestedUpdates()216  // warnAboutRenderPhaseUpdatesInDEV(fiber);217  const root = markUpdateLaneFromFiberToRoot(fiber, lane);218  if (root === null) {219    //   warnAboutUpdateOnUnmountedFiberInDEV(fiber);220    return null;221  }222  // Mark that the root has a pending update.223  markRootUpdated(root, lane, eventTime);224  // if (enableProfilerTimer && enableProfilerNestedUpdateScheduledHook) {225  //     // ...226  // }227  if (root === workInProgressRoot) {228    // Received an update to a tree that's in the middle of rendering. Mark229    // that there was an interleaved update work on this root. Unless the230    // `deferRenderPhaseUpdateToNextBatch` flag is off and this is a render...scheduleUpdateOnFiber.js
Source:scheduleUpdateOnFiber.js  
...14 * @param {*} eventTime 15 */16function scheduleUpdateOnFiber(fiber, lane, eventTime) {17  //checkForNestedUpdates();18  //warnAboutRenderPhaseUpdatesInDEV(fiber);19  // å䏿¾å°è·èç¹ root20  var root = markUpdateLaneFromFiberToRoot(fiber, lane);21  ensureRootIsScheduled(root, eventTime);22  // 妿å½åçæ§è¡ä¸ä¸æç¯å¢æ¯NoContextï¼éæ¹éï¼å¹¶ä¸Mode䏿¯å¹¶åçè¯23  if (executionContext === NoContext && (fiber.mode & ConcurrentMode) === NoMode) {24    flushSyncCallbackQueue();25  }26}27// ä»å½åfiberèç¹ï¼é彿¾å°root28function markUpdateLaneFromFiberToRoot(fiber) {29  let parent = fiber.return;30  while(parent) {31    fiber = parent;32    parent = fiber.return;...tips.stories.js
Source:tips.stories.js  
1import React from 'react';2import { Paper } from '@material-ui/core';3import { renderMarkdown } from "../../utils/markdown";4import mdFile from "./question.md";5export default {6  title: 'ReactJs/Tips',7};8export const connectionError = () => {9  const error = `react_devtools_backend.js:6 Warning: Cannot update a component ('ConnectFunction') while rendering a different component ('MainPage'). To locate the bad setState() call inside 'MainPage', follow the stack trace as described in https://fb.me/setstate-in-render10  in MainPage (created by ConnectFunction)11  in ConnectFunction (created by Context.Consumer)12  in Route (created by PrivateRoute)13  in PrivateRoute (created by App)14  in Switch (created by App)15  in div (created by App)16  in Router (created by HashRouter)17  in HashRouter (created by App)18  in App (created by HotExportedApp)19  in AppContainer (created by HotExportedApp)20  in HotExportedApp21  in Provider22r @ react_devtools_backend.js:623printWarning @ react-dom.development.js?61bb:8824error @ react-dom.development.js?61bb:6025warnAboutRenderPhaseUpdatesInDEV @ react-dom.development.js?61bb:2324126scheduleUpdateOnFiber @ react-dom.development.js?61bb:2116527dispatchAction @ react-dom.development.js?61bb:1566028checkForUpdates @ connectAdvanced.js?fe33:8829handleChangeWrapper @ Subscription.js?79d6:9730eval @ Subscription.js?79d6:2331batchedUpdates$1 @ react-dom.development.js?61bb:2185632notify @ Subscription.js?79d6:1933notifyNestedSubs @ Subscription.js?79d6:9234handleChangeWrapper @ Subscription.js?79d6:9735dispatch @ redux.js?00d8:22236e @ VM68371:137eval @ redux.js?00d8:47738render @ index.js?98ac:5239finishClassComponent @ react-dom.development.js?61bb:1716040updateClassComponent @ react-dom.development.js?61bb:1711041beginWork @ react-dom.development.js?61bb:1862042beginWork$1 @ react-dom.development.js?61bb:2317943performUnitOfWork @ react-dom.development.js?61bb:2215444workLoopSync @ react-dom.development.js?61bb:2213045performSyncWorkOnRoot @ react-dom.development.js?61bb:2175646eval @ react-dom.development.js?61bb:1108947unstable_runWithPriority @ scheduler.development.js?3069:65348runWithPriority$1 @ react-dom.development.js?61bb:1103949flushSyncCallbackQueueImpl @ react-dom.development.js?61bb:1108450flushSyncCallbackQueue @ react-dom.development.js?61bb:1107251discreteUpdates$1 @ react-dom.development.js?61bb:2189352discreteUpdates @ react-dom.development.js?61bb:80653dispatchDiscreteEvent @ react-dom.development.js?61bb:416854Show 2 more frames`;55  return (56    <div>57      <Paper>58        {renderMarkdown(mdFile)}59      </Paper>60    </div>61  )...Using AI Code Generation
1const { chromium } = require('playwright');2(async () => {3  const browser = await chromium.launch();4  const context = await browser.newContext();5  const page = await context.newPage();6  await page.screenshot({ path: 'google.png' });7  await browser.close();8})();9const { chromium } = require('playwright');10(async () => {11  const browser = await chromium.launch();12  const context = await browser.newContext();13  const page = await context.newPage();14  await page.screenshot({ path: 'google.png' });15  await browser.close();16})();17const { chromium } = require('playwright');18(async () => {19  const browser = await chromium.launch();20  const context = await browser.newContext();21  const page = await context.newPage();22  await page.screenshot({ path: 'google.png' });23  await browser.close();24})();25const { chromium } = require('playwright');26(async () => {27  const browser = await chromium.launch();28  const context = await browser.newContext();29  const page = await context.newPage();30  await page.screenshot({ path: 'google.png' });31  await browser.close();32})();33const { chromium } = require('playwright');34(async () => {35  const browser = await chromium.launch();36  const context = await browser.newContext();37  const page = await context.newPage();38  await page.screenshot({ path: 'google.png' });39  await browser.close();40})();41const { chromium } = require('playwright');42(async () => {43  const browser = await chromium.launch();Using AI Code Generation
1const { PlaywrightInternal } = require('playwright/lib/server/playwright');2const { warnAboutRenderPhaseUpdatesInDEV } = PlaywrightInternal;3const { PlaywrightInternal } = require('playwright/lib/server/playwright');4const { warnAboutRenderPhaseUpdatesInDEV } = PlaywrightInternal;5const { PlaywrightInternal } = require('playwright/lib/server/playwright');6const { warnAboutRenderPhaseUpdatesInDEV } = PlaywrightInternal;7const { PlaywrightInternal } = require('playwright/lib/server/playwright');8const { warnAboutRenderPhaseUpdatesInDEV } = PlaywrightInternal;9const { PlaywrightInternal } = require('playwright/lib/server/playwright');10const { warnAboutRenderPhaseUpdatesInDEV } = PlaywrightInternal;11const { PlaywrightInternal } = require('playwright/lib/server/playwright');12const { warnAboutRenderPhaseUpdatesInDEV } = PlaywrightInternal;13const { PlaywrightInternal } = require('playwright/lib/server/playwright');14const { warnAboutRenderPhaseUpdatesInDEV } = PlaywrightInternal;15const { PlaywrightInternal } = require('playwright/lib/server/playwright');16const { warnAboutRenderPhaseUpdatesInDEV } = PlaywrightInternal;17const { PlaywrightInternal } = require('playwright/lib/server/playwright');18const { warnAboutRenderPhaseUpdatesInDEV } = PlaywrightInternal;19const { PlaywrightInternal } = require('playwright/lib/server/playwright');20const { warnAboutRenderPhaseUpdatesInDEV } = PlaywrightInternal;21const { PlaywrightInternal } =Using AI Code Generation
1import { warnAboutRenderPhaseUpdatesInDEV } from 'react-reconciler/src/ReactFiberDevToolsHook.new';2warnAboutRenderPhaseUpdatesInDEV = () => {};3const { chromium } = require('playwright');4(async () => {5  const browser = await chromium.launch();6  const context = await browser.newContext();7  const page = await context.newPage();8  await page.screenshot({ path: `example.png` });9  await browser.close();10})();11import { warnAboutRenderPhaseUpdatesInDEV } from 'react-reconciler/src/ReactFiberDevToolsHook.new';12warnAboutRenderPhaseUpdatesInDEV = () => {};13const { chromium } = require('playwright');14(async () => {15  const browser = await chromium.launch();16  const context = await browser.newContext();17  const page = await context.newPage();18  await page.screenshot({ path: `example.png` });19  await browser.close();20})();21import { warnAboutRenderPhaseUpdatesInDEV } from 'react-reconciler/src/ReactFiberDevToolsHook.new';22warnAboutRenderPhaseUpdatesInDEV = () => {};23const { chromium } = require('playwright');24(async () => {25  const browser = await chromium.launch();26  const context = await browser.newContext();27  const page = await context.newPage();28  await page.screenshot({ path: `example.png` });29  await browser.close();30})();31import { warnAboutRenderPhaseUpdatesInDEV } from 'react-reconciler/src/ReactFiberDevToolsHook.new';32warnAboutRenderPhaseUpdatesInDEV = () => {};33const { chromium } = require('playwright');34(async () => {35  const browser = await chromium.launch();Using AI Code Generation
1const { warnAboutRenderPhaseUpdatesInDEV } = require('playwright/lib/server/common/Debug');2warnAboutRenderPhaseUpdatesInDEV();3const { warnAboutRenderPhaseUpdatesInDEV } = require('playwright/lib/server/common/Debug');4warnAboutRenderPhaseUpdatesInDEV();5const { warnAboutRenderPhaseUpdatesInDEV } = require('playwright/lib/server/common/Debug');6warnAboutRenderPhaseUpdatesInDEV();7const { chromium } = require('playwright');8(async () => {9const browser = await chromium.launch({10});11const context = await browser.newContext();12const page = await context.newPage();13await page.screenshot({ path: `example.png` });14await browser.close();15})();16Your name to display (optionaUsing AI Code Generation
1const { warnAboutRenderPhaseUpdatesInDEV } = require('@playwright/test/lib/server/react');2warnAboutRenderPhaseUpdatesInDEV('test');3I am using the following code to import the module:4const { warnAboutRenderPhaseUpdatesInDEV } = require('@playwright/test/lib/server/react');5I am using the following code to import the module:6const { warnAboutRenderPhaseUpdatesInDEV } = require('@playwright/test/lib/server/react');7I am using the following code to import the module:8const { warnAboutRenderPhaseUpdatesInDEV } = require('@playwright/test/lib/server/react');LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.
Get 100 minutes of automation test minutes FREE!!
