diff --git a/packages/react-reconciler/src/ReactFiberWorkLoop.js b/packages/react-reconciler/src/ReactFiberWorkLoop.js index 43606d805f0e2..389ff45ff3232 100644 --- a/packages/react-reconciler/src/ReactFiberWorkLoop.js +++ b/packages/react-reconciler/src/ReactFiberWorkLoop.js @@ -325,18 +325,6 @@ export function computeExpirationForFiber( return renderExpirationTime; } - if ((executionContext & CommitContext) !== NoContext) { - if (pendingPassiveEffectsExpirationTime === Never) { - // Updates triggered by an effect inside an offscreen tree should be - // Never, not Idle. - // TODO: This wouldn't be necessary if we deprioritized offscreen updates - // when traversing the return path (`markUpdateTimeFromFiberToRoot`), - // instead of waiting to bail out in the render phase. - // TODO: Should there be a way to opt out, like with `runWithPriority`? - return Never; - } - } - let expirationTime; if (suspenseConfig !== null) { // Compute an expiration time based on the Suspense timeout. @@ -2231,7 +2219,9 @@ function flushPassiveEffectsImpl() { return false; } const root = rootWithPendingPassiveEffects; + const expirationTime = pendingPassiveEffectsExpirationTime; rootWithPendingPassiveEffects = null; + pendingPassiveEffectsExpirationTime = NoWork; invariant( (executionContext & (RenderContext | CommitContext)) === NoContext, @@ -2271,11 +2261,10 @@ function flushPassiveEffectsImpl() { if (enableSchedulerTracing) { popInteractions(((prevInteractions: any): Set)); - finishPendingInteractions(root, pendingPassiveEffectsExpirationTime); + finishPendingInteractions(root, expirationTime); } executionContext = prevExecutionContext; - pendingPassiveEffectsExpirationTime = NoWork; flushSyncCallbackQueue(); diff --git a/packages/react/src/__tests__/ReactDOMTracing-test.internal.js b/packages/react/src/__tests__/ReactDOMTracing-test.internal.js index 8d0a6a5cd0f84..99546e80bfcfb 100644 --- a/packages/react/src/__tests__/ReactDOMTracing-test.internal.js +++ b/packages/react/src/__tests__/ReactDOMTracing-test.internal.js @@ -134,7 +134,12 @@ describe('ReactDOMTracing', () => { expect( onInteractionScheduledWorkCompleted, ).toHaveBeenLastNotifiedOfInteraction(interaction); - expect(onRender).toHaveBeenCalledTimes(3); + // TODO: This is 4 instead of 3 because this update was scheduled at + // idle priority, and idle updates are slightly higher priority than + // offscreen work. So it takes two render passes to finish it. Profiler + // calls `onRender` for the first render even though everything + // bails out. + expect(onRender).toHaveBeenCalledTimes(4); expect(onRender).toHaveLastRenderedWithInteractions( new Set([interaction]), ); @@ -281,11 +286,11 @@ describe('ReactDOMTracing', () => { expect( onInteractionScheduledWorkCompleted, ).toHaveBeenLastNotifiedOfInteraction(interaction); - // TODO: This is 4 instead of 3 because this update was explicitly - // scheduled at idle priority, and idle updates are slightly higher - // priority than offscreen work. So it takes two render passes to finish - // it. Profiler calls `onRender` for the first render even though - // everything bails out. + // TODO: This is 4 instead of 3 because this update was scheduled at + // idle priority, and idle updates are slightly higher priority than + // offscreen work. So it takes two render passes to finish it. Profiler + // calls `onRender` for the first render even though everything + // bails out. expect(onRender).toHaveBeenCalledTimes(4); expect(onRender).toHaveLastRenderedWithInteractions( new Set([interaction]),