From 92fcd46cc79bbf45df4ce86b0678dcef3b91078d Mon Sep 17 00:00:00 2001 From: Andrew Clark Date: Fri, 28 Aug 2020 12:52:56 -0500 Subject: [PATCH] Replace SuspenseConfig object with an integer (#19706) Now that the options in SuspenseConfig are no longer supported, the only thing we use it for is to track whether an update is part of a transition. I've renamed `ReactCurrentBatchConfig.suspense` to `ReactCurrentBatchConfig.transition`, and changed the type to a number. The number is always either 0 or 1. I could have made it a boolean; however, most likely this will eventually be either a Lane or an incrementing identifier. The `withSuspenseConfig` export still exists until we've removed all the callers from www. --- .../react-debug-tools/src/ReactDebugHooks.js | 2 +- .../src/server/ReactPartialRendererHooks.js | 2 +- .../src/ReactFiberClassComponent.new.js | 10 ++--- .../src/ReactFiberClassComponent.old.js | 10 ++--- .../src/ReactFiberHooks.new.js | 42 +++++++++---------- .../src/ReactFiberHooks.old.js | 42 +++++++++---------- .../src/ReactFiberReconciler.new.js | 6 +-- .../src/ReactFiberReconciler.old.js | 6 +-- ...penseConfig.js => ReactFiberTransition.js} | 12 ++++-- .../src/ReactFiberWorkLoop.new.js | 13 ++---- .../src/ReactFiberWorkLoop.old.js | 13 ++---- .../src/ReactInternalTypes.js | 2 +- packages/react/src/ReactBatchConfig.js | 14 ++++--- packages/react/src/ReactCurrentBatchConfig.js | 4 +- packages/react/src/ReactStartTransition.js | 10 ++--- 15 files changed, 80 insertions(+), 108 deletions(-) rename packages/react-reconciler/src/{ReactFiberSuspenseConfig.js => ReactFiberTransition.js} (75%) diff --git a/packages/react-debug-tools/src/ReactDebugHooks.js b/packages/react-debug-tools/src/ReactDebugHooks.js index 31e03102b440d..7c6736f5caf4e 100644 --- a/packages/react-debug-tools/src/ReactDebugHooks.js +++ b/packages/react-debug-tools/src/ReactDebugHooks.js @@ -20,7 +20,7 @@ import type { } from 'react-reconciler/src/ReactInternalTypes'; import type {OpaqueIDType} from 'react-reconciler/src/ReactFiberHostConfig'; -import type {SuspenseConfig} from 'react-reconciler/src/ReactFiberSuspenseConfig'; +import type {SuspenseConfig} from 'react-reconciler/src/ReactFiberTransition'; import {NoMode} from 'react-reconciler/src/ReactTypeOfMode'; import ErrorStackParser from 'error-stack-parser'; diff --git a/packages/react-dom/src/server/ReactPartialRendererHooks.js b/packages/react-dom/src/server/ReactPartialRendererHooks.js index 302a6682b443f..ec78aac9121b5 100644 --- a/packages/react-dom/src/server/ReactPartialRendererHooks.js +++ b/packages/react-dom/src/server/ReactPartialRendererHooks.js @@ -15,7 +15,7 @@ import type { MutableSourceSubscribeFn, ReactContext, } from 'shared/ReactTypes'; -import type {SuspenseConfig} from 'react-reconciler/src/ReactFiberSuspenseConfig'; +import type {SuspenseConfig} from 'react-reconciler/src/ReactFiberTransition'; import type PartialRenderer from './ReactPartialRenderer'; import {validateContextBounds} from './ReactPartialRendererContext'; diff --git a/packages/react-reconciler/src/ReactFiberClassComponent.new.js b/packages/react-reconciler/src/ReactFiberClassComponent.new.js index 59914edf43398..c4a84b670207c 100644 --- a/packages/react-reconciler/src/ReactFiberClassComponent.new.js +++ b/packages/react-reconciler/src/ReactFiberClassComponent.new.js @@ -56,7 +56,6 @@ import { requestUpdateLane, scheduleUpdateOnFiber, } from './ReactFiberWorkLoop.new'; -import {requestCurrentSuspenseConfig} from './ReactFiberSuspenseConfig'; import {logForceUpdateScheduled, logStateUpdateScheduled} from './DebugTracing'; import {disableLogs, reenableLogs} from 'shared/ConsolePatchingDev'; @@ -196,8 +195,7 @@ const classComponentUpdater = { enqueueSetState(inst, payload, callback) { const fiber = getInstance(inst); const eventTime = requestEventTime(); - const suspenseConfig = requestCurrentSuspenseConfig(); - const lane = requestUpdateLane(fiber, suspenseConfig); + const lane = requestUpdateLane(fiber); const update = createUpdate(eventTime, lane); update.payload = payload; @@ -227,8 +225,7 @@ const classComponentUpdater = { enqueueReplaceState(inst, payload, callback) { const fiber = getInstance(inst); const eventTime = requestEventTime(); - const suspenseConfig = requestCurrentSuspenseConfig(); - const lane = requestUpdateLane(fiber, suspenseConfig); + const lane = requestUpdateLane(fiber); const update = createUpdate(eventTime, lane); update.tag = ReplaceState; @@ -260,8 +257,7 @@ const classComponentUpdater = { enqueueForceUpdate(inst, callback) { const fiber = getInstance(inst); const eventTime = requestEventTime(); - const suspenseConfig = requestCurrentSuspenseConfig(); - const lane = requestUpdateLane(fiber, suspenseConfig); + const lane = requestUpdateLane(fiber); const update = createUpdate(eventTime, lane); update.tag = ForceUpdate; diff --git a/packages/react-reconciler/src/ReactFiberClassComponent.old.js b/packages/react-reconciler/src/ReactFiberClassComponent.old.js index d05c494f1ba6d..ad8c0b153d784 100644 --- a/packages/react-reconciler/src/ReactFiberClassComponent.old.js +++ b/packages/react-reconciler/src/ReactFiberClassComponent.old.js @@ -56,7 +56,6 @@ import { requestUpdateLane, scheduleUpdateOnFiber, } from './ReactFiberWorkLoop.old'; -import {requestCurrentSuspenseConfig} from './ReactFiberSuspenseConfig'; import {logForceUpdateScheduled, logStateUpdateScheduled} from './DebugTracing'; import {disableLogs, reenableLogs} from 'shared/ConsolePatchingDev'; @@ -196,8 +195,7 @@ const classComponentUpdater = { enqueueSetState(inst, payload, callback) { const fiber = getInstance(inst); const eventTime = requestEventTime(); - const suspenseConfig = requestCurrentSuspenseConfig(); - const lane = requestUpdateLane(fiber, suspenseConfig); + const lane = requestUpdateLane(fiber); const update = createUpdate(eventTime, lane); update.payload = payload; @@ -227,8 +225,7 @@ const classComponentUpdater = { enqueueReplaceState(inst, payload, callback) { const fiber = getInstance(inst); const eventTime = requestEventTime(); - const suspenseConfig = requestCurrentSuspenseConfig(); - const lane = requestUpdateLane(fiber, suspenseConfig); + const lane = requestUpdateLane(fiber); const update = createUpdate(eventTime, lane); update.tag = ReplaceState; @@ -260,8 +257,7 @@ const classComponentUpdater = { enqueueForceUpdate(inst, callback) { const fiber = getInstance(inst); const eventTime = requestEventTime(); - const suspenseConfig = requestCurrentSuspenseConfig(); - const lane = requestUpdateLane(fiber, suspenseConfig); + const lane = requestUpdateLane(fiber); const update = createUpdate(eventTime, lane); update.tag = ForceUpdate; diff --git a/packages/react-reconciler/src/ReactFiberHooks.new.js b/packages/react-reconciler/src/ReactFiberHooks.new.js index 2fc397f470164..820d6972f1045 100644 --- a/packages/react-reconciler/src/ReactFiberHooks.new.js +++ b/packages/react-reconciler/src/ReactFiberHooks.new.js @@ -16,7 +16,7 @@ import type { import type {Fiber, Dispatcher} from './ReactInternalTypes'; import type {Lanes, Lane} from './ReactFiberLane'; import type {HookEffectTag} from './ReactHookEffectTags'; -import type {SuspenseConfig} from './ReactFiberSuspenseConfig'; +import type {SuspenseConfig} from './ReactFiberTransition'; import type {ReactPriorityLevel} from './ReactInternalTypes'; import type {FiberRoot} from './ReactInternalTypes'; import type {OpaqueIDType} from './ReactFiberHostConfig'; @@ -70,7 +70,6 @@ import invariant from 'shared/invariant'; import getComponentName from 'shared/getComponentName'; import is from 'shared/objectIs'; import {markWorkInProgressReceivedUpdate} from './ReactFiberBeginWork.new'; -import {requestCurrentSuspenseConfig} from './ReactFiberSuspenseConfig'; import { UserBlockingPriority, NormalPriority, @@ -1003,8 +1002,7 @@ function useMutableSource( if (!is(snapshot, maybeNewSnapshot)) { setSnapshot(maybeNewSnapshot); - const suspenseConfig = requestCurrentSuspenseConfig(); - const lane = requestUpdateLane(fiber, suspenseConfig); + const lane = requestUpdateLane(fiber); markRootMutableRead(root, lane); } // If the source mutated between render and now, @@ -1024,8 +1022,7 @@ function useMutableSource( latestSetSnapshot(latestGetSnapshot(source._source)); // Record a pending mutable source update with the same expiration time. - const suspenseConfig = requestCurrentSuspenseConfig(); - const lane = requestUpdateLane(fiber, suspenseConfig); + const lane = requestUpdateLane(fiber); markRootMutableRead(root, lane); } catch (error) { @@ -1441,12 +1438,12 @@ function mountDeferredValue( ): T { const [prevValue, setValue] = mountState(value); mountEffect(() => { - const previousConfig = ReactCurrentBatchConfig.suspense; - ReactCurrentBatchConfig.suspense = config === undefined ? null : config; + const prevTransition = ReactCurrentBatchConfig.transition; + ReactCurrentBatchConfig.transition = 1; try { setValue(value); } finally { - ReactCurrentBatchConfig.suspense = previousConfig; + ReactCurrentBatchConfig.transition = prevTransition; } }, [value, config]); return prevValue; @@ -1458,12 +1455,12 @@ function updateDeferredValue( ): T { const [prevValue, setValue] = updateState(value); updateEffect(() => { - const previousConfig = ReactCurrentBatchConfig.suspense; - ReactCurrentBatchConfig.suspense = config === undefined ? null : config; + const prevTransition = ReactCurrentBatchConfig.transition; + ReactCurrentBatchConfig.transition = 1; try { setValue(value); } finally { - ReactCurrentBatchConfig.suspense = previousConfig; + ReactCurrentBatchConfig.transition = prevTransition; } }, [value, config]); return prevValue; @@ -1475,12 +1472,12 @@ function rerenderDeferredValue( ): T { const [prevValue, setValue] = rerenderState(value); updateEffect(() => { - const previousConfig = ReactCurrentBatchConfig.suspense; - ReactCurrentBatchConfig.suspense = config === undefined ? null : config; + const prevTransition = ReactCurrentBatchConfig.transition; + ReactCurrentBatchConfig.transition = 1; try { setValue(value); } finally { - ReactCurrentBatchConfig.suspense = previousConfig; + ReactCurrentBatchConfig.transition = prevTransition; } }, [value, config]); return prevValue; @@ -1509,8 +1506,8 @@ function startTransition(setPending, config, callback) { runWithPriority( priorityLevel > NormalPriority ? NormalPriority : priorityLevel, () => { - const previousConfig = ReactCurrentBatchConfig.suspense; - ReactCurrentBatchConfig.suspense = config === undefined ? null : config; + const prevTransition = ReactCurrentBatchConfig.transition; + ReactCurrentBatchConfig.transition = 1; try { setPending(false); callback(); @@ -1518,7 +1515,7 @@ function startTransition(setPending, config, callback) { if (decoupleUpdatePriorityFromScheduler) { setCurrentUpdateLanePriority(previousLanePriority); } - ReactCurrentBatchConfig.suspense = previousConfig; + ReactCurrentBatchConfig.transition = prevTransition; } }, ); @@ -1535,13 +1532,13 @@ function startTransition(setPending, config, callback) { runWithPriority( priorityLevel > NormalPriority ? NormalPriority : priorityLevel, () => { - const previousConfig = ReactCurrentBatchConfig.suspense; - ReactCurrentBatchConfig.suspense = config === undefined ? null : config; + const prevTransition = ReactCurrentBatchConfig.transition; + ReactCurrentBatchConfig.transition = 1; try { setPending(false); callback(); } finally { - ReactCurrentBatchConfig.suspense = previousConfig; + ReactCurrentBatchConfig.transition = prevTransition; } }, ); @@ -1685,8 +1682,7 @@ function dispatchAction( } const eventTime = requestEventTime(); - const suspenseConfig = requestCurrentSuspenseConfig(); - const lane = requestUpdateLane(fiber, suspenseConfig); + const lane = requestUpdateLane(fiber); const update: Update = { lane, diff --git a/packages/react-reconciler/src/ReactFiberHooks.old.js b/packages/react-reconciler/src/ReactFiberHooks.old.js index 32320c2c35a94..64951ef662670 100644 --- a/packages/react-reconciler/src/ReactFiberHooks.old.js +++ b/packages/react-reconciler/src/ReactFiberHooks.old.js @@ -16,7 +16,7 @@ import type { import type {Fiber, Dispatcher} from './ReactInternalTypes'; import type {Lanes, Lane} from './ReactFiberLane'; import type {HookEffectTag} from './ReactHookEffectTags'; -import type {SuspenseConfig} from './ReactFiberSuspenseConfig'; +import type {SuspenseConfig} from './ReactFiberTransition'; import type {ReactPriorityLevel} from './ReactInternalTypes'; import type {FiberRoot} from './ReactInternalTypes'; import type {OpaqueIDType} from './ReactFiberHostConfig'; @@ -69,7 +69,6 @@ import invariant from 'shared/invariant'; import getComponentName from 'shared/getComponentName'; import is from 'shared/objectIs'; import {markWorkInProgressReceivedUpdate} from './ReactFiberBeginWork.old'; -import {requestCurrentSuspenseConfig} from './ReactFiberSuspenseConfig'; import { UserBlockingPriority, NormalPriority, @@ -1002,8 +1001,7 @@ function useMutableSource( if (!is(snapshot, maybeNewSnapshot)) { setSnapshot(maybeNewSnapshot); - const suspenseConfig = requestCurrentSuspenseConfig(); - const lane = requestUpdateLane(fiber, suspenseConfig); + const lane = requestUpdateLane(fiber); markRootMutableRead(root, lane); } // If the source mutated between render and now, @@ -1023,8 +1021,7 @@ function useMutableSource( latestSetSnapshot(latestGetSnapshot(source._source)); // Record a pending mutable source update with the same expiration time. - const suspenseConfig = requestCurrentSuspenseConfig(); - const lane = requestUpdateLane(fiber, suspenseConfig); + const lane = requestUpdateLane(fiber); markRootMutableRead(root, lane); } catch (error) { @@ -1440,12 +1437,12 @@ function mountDeferredValue( ): T { const [prevValue, setValue] = mountState(value); mountEffect(() => { - const previousConfig = ReactCurrentBatchConfig.suspense; - ReactCurrentBatchConfig.suspense = config === undefined ? null : config; + const prevTransition = ReactCurrentBatchConfig.transition; + ReactCurrentBatchConfig.transition = 1; try { setValue(value); } finally { - ReactCurrentBatchConfig.suspense = previousConfig; + ReactCurrentBatchConfig.transition = prevTransition; } }, [value, config]); return prevValue; @@ -1457,12 +1454,12 @@ function updateDeferredValue( ): T { const [prevValue, setValue] = updateState(value); updateEffect(() => { - const previousConfig = ReactCurrentBatchConfig.suspense; - ReactCurrentBatchConfig.suspense = config === undefined ? null : config; + const prevTransition = ReactCurrentBatchConfig.transition; + ReactCurrentBatchConfig.transition = 1; try { setValue(value); } finally { - ReactCurrentBatchConfig.suspense = previousConfig; + ReactCurrentBatchConfig.transition = prevTransition; } }, [value, config]); return prevValue; @@ -1474,12 +1471,12 @@ function rerenderDeferredValue( ): T { const [prevValue, setValue] = rerenderState(value); updateEffect(() => { - const previousConfig = ReactCurrentBatchConfig.suspense; - ReactCurrentBatchConfig.suspense = config === undefined ? null : config; + const prevTransition = ReactCurrentBatchConfig.transition; + ReactCurrentBatchConfig.transition = 1; try { setValue(value); } finally { - ReactCurrentBatchConfig.suspense = previousConfig; + ReactCurrentBatchConfig.transition = prevTransition; } }, [value, config]); return prevValue; @@ -1508,8 +1505,8 @@ function startTransition(setPending, config, callback) { runWithPriority( priorityLevel > NormalPriority ? NormalPriority : priorityLevel, () => { - const previousConfig = ReactCurrentBatchConfig.suspense; - ReactCurrentBatchConfig.suspense = config === undefined ? null : config; + const prevTransition = ReactCurrentBatchConfig.transition; + ReactCurrentBatchConfig.transition = 1; try { setPending(false); callback(); @@ -1517,7 +1514,7 @@ function startTransition(setPending, config, callback) { if (decoupleUpdatePriorityFromScheduler) { setCurrentUpdateLanePriority(previousLanePriority); } - ReactCurrentBatchConfig.suspense = previousConfig; + ReactCurrentBatchConfig.transition = prevTransition; } }, ); @@ -1534,13 +1531,13 @@ function startTransition(setPending, config, callback) { runWithPriority( priorityLevel > NormalPriority ? NormalPriority : priorityLevel, () => { - const previousConfig = ReactCurrentBatchConfig.suspense; - ReactCurrentBatchConfig.suspense = config === undefined ? null : config; + const prevTransition = ReactCurrentBatchConfig.transition; + ReactCurrentBatchConfig.transition = 1; try { setPending(false); callback(); } finally { - ReactCurrentBatchConfig.suspense = previousConfig; + ReactCurrentBatchConfig.transition = prevTransition; } }, ); @@ -1683,8 +1680,7 @@ function dispatchAction( } const eventTime = requestEventTime(); - const suspenseConfig = requestCurrentSuspenseConfig(); - const lane = requestUpdateLane(fiber, suspenseConfig); + const lane = requestUpdateLane(fiber); const update: Update = { lane, diff --git a/packages/react-reconciler/src/ReactFiberReconciler.new.js b/packages/react-reconciler/src/ReactFiberReconciler.new.js index fd90dda8e961c..6d514d2f2a369 100644 --- a/packages/react-reconciler/src/ReactFiberReconciler.new.js +++ b/packages/react-reconciler/src/ReactFiberReconciler.new.js @@ -83,7 +83,6 @@ import { getCurrentUpdateLanePriority, setCurrentUpdateLanePriority, } from './ReactFiberLane'; -import {requestCurrentSuspenseConfig} from './ReactFiberSuspenseConfig'; import { scheduleRefresh, scheduleRoot, @@ -266,8 +265,7 @@ export function updateContainer( warnIfNotScopedWithMatchingAct(current); } } - const suspenseConfig = requestCurrentSuspenseConfig(); - const lane = requestUpdateLane(current, suspenseConfig); + const lane = requestUpdateLane(current); if (enableSchedulingProfiler) { markRenderScheduled(lane); @@ -427,7 +425,7 @@ export function attemptHydrationAtCurrentPriority(fiber: Fiber): void { return; } const eventTime = requestEventTime(); - const lane = requestUpdateLane(fiber, null); + const lane = requestUpdateLane(fiber); scheduleUpdateOnFiber(fiber, lane, eventTime); markRetryLaneIfNotHydrated(fiber, lane); } diff --git a/packages/react-reconciler/src/ReactFiberReconciler.old.js b/packages/react-reconciler/src/ReactFiberReconciler.old.js index 549d69724385d..5aa381ea4e5cd 100644 --- a/packages/react-reconciler/src/ReactFiberReconciler.old.js +++ b/packages/react-reconciler/src/ReactFiberReconciler.old.js @@ -83,7 +83,6 @@ import { getCurrentUpdateLanePriority, setCurrentUpdateLanePriority, } from './ReactFiberLane'; -import {requestCurrentSuspenseConfig} from './ReactFiberSuspenseConfig'; import { scheduleRefresh, scheduleRoot, @@ -266,8 +265,7 @@ export function updateContainer( warnIfNotScopedWithMatchingAct(current); } } - const suspenseConfig = requestCurrentSuspenseConfig(); - const lane = requestUpdateLane(current, suspenseConfig); + const lane = requestUpdateLane(current); if (enableSchedulingProfiler) { markRenderScheduled(lane); @@ -427,7 +425,7 @@ export function attemptHydrationAtCurrentPriority(fiber: Fiber): void { return; } const eventTime = requestEventTime(); - const lane = requestUpdateLane(fiber, null); + const lane = requestUpdateLane(fiber); scheduleUpdateOnFiber(fiber, lane, eventTime); markRetryLaneIfNotHydrated(fiber, lane); } diff --git a/packages/react-reconciler/src/ReactFiberSuspenseConfig.js b/packages/react-reconciler/src/ReactFiberTransition.js similarity index 75% rename from packages/react-reconciler/src/ReactFiberSuspenseConfig.js rename to packages/react-reconciler/src/ReactFiberTransition.js index 752c5fed38a22..dac8015358f76 100644 --- a/packages/react-reconciler/src/ReactFiberSuspenseConfig.js +++ b/packages/react-reconciler/src/ReactFiberTransition.js @@ -9,18 +9,22 @@ import ReactSharedInternals from 'shared/ReactSharedInternals'; -const {ReactCurrentBatchConfig} = ReactSharedInternals; - +// Deprecated export type SuspenseConfig = {| timeoutMs: number, busyDelayMs?: number, busyMinDurationMs?: number, |}; +// Deprecated export type TimeoutConfig = {| timeoutMs: number, |}; -export function requestCurrentSuspenseConfig(): null | SuspenseConfig { - return ReactCurrentBatchConfig.suspense; +const {ReactCurrentBatchConfig} = ReactSharedInternals; + +export const NoTransition = 0; + +export function requestCurrentTransition(): number { + return ReactCurrentBatchConfig.transition; } diff --git a/packages/react-reconciler/src/ReactFiberWorkLoop.new.js b/packages/react-reconciler/src/ReactFiberWorkLoop.new.js index 4205a65ba4f10..acf2da879d227 100644 --- a/packages/react-reconciler/src/ReactFiberWorkLoop.new.js +++ b/packages/react-reconciler/src/ReactFiberWorkLoop.new.js @@ -12,7 +12,6 @@ import type {Fiber, FiberRoot} from './ReactInternalTypes'; import type {Lanes, Lane} from './ReactFiberLane'; import type {ReactPriorityLevel} from './ReactInternalTypes'; import type {Interaction} from 'scheduler/src/Tracing'; -import type {SuspenseConfig} from './ReactFiberSuspenseConfig'; import type {SuspenseState} from './ReactFiberSuspenseComponent.new'; import type {StackCursor} from './ReactFiberStack.new'; import type {FunctionComponentUpdateQueue} from './ReactFiberHooks.new'; @@ -188,6 +187,7 @@ import { schedulerPriorityToLanePriority, lanePriorityToSchedulerPriority, } from './ReactFiberLane'; +import {requestCurrentTransition, NoTransition} from './ReactFiberTransition'; import {beginWork as originalBeginWork} from './ReactFiberBeginWork.new'; import {completeWork} from './ReactFiberCompleteWork.new'; import {unwindWork, unwindInterruptedWork} from './ReactFiberUnwindWork.new'; @@ -402,10 +402,7 @@ export function getCurrentTime() { return now(); } -export function requestUpdateLane( - fiber: Fiber, - suspenseConfig: SuspenseConfig | null, -): Lane { +export function requestUpdateLane(fiber: Fiber): Lane { // Special cases const mode = fiber.mode; if ((mode & BlockingMode) === NoMode) { @@ -449,10 +446,8 @@ export function requestUpdateLane( currentEventWipLanes = workInProgressRootIncludedLanes; } - if (suspenseConfig !== null) { - // Use the size of the timeout as a heuristic to prioritize shorter - // transitions over longer ones. - // TODO: This will coerce numbers larger than 31 bits to 0. + const isTransition = requestCurrentTransition() !== NoTransition; + if (isTransition) { if (currentEventPendingLanes !== NoLanes) { currentEventPendingLanes = mostRecentlyUpdatedRoot !== null diff --git a/packages/react-reconciler/src/ReactFiberWorkLoop.old.js b/packages/react-reconciler/src/ReactFiberWorkLoop.old.js index 47dae385793b8..4e62a84e9a2ce 100644 --- a/packages/react-reconciler/src/ReactFiberWorkLoop.old.js +++ b/packages/react-reconciler/src/ReactFiberWorkLoop.old.js @@ -12,7 +12,6 @@ import type {Fiber, FiberRoot} from './ReactInternalTypes'; import type {Lanes, Lane} from './ReactFiberLane'; import type {ReactPriorityLevel} from './ReactInternalTypes'; import type {Interaction} from 'scheduler/src/Tracing'; -import type {SuspenseConfig} from './ReactFiberSuspenseConfig'; import type {SuspenseState} from './ReactFiberSuspenseComponent.old'; import type {Effect as HookEffect} from './ReactFiberHooks.old'; import type {StackCursor} from './ReactFiberStack.old'; @@ -174,6 +173,7 @@ import { schedulerPriorityToLanePriority, lanePriorityToSchedulerPriority, } from './ReactFiberLane'; +import {requestCurrentTransition, NoTransition} from './ReactFiberTransition'; import {beginWork as originalBeginWork} from './ReactFiberBeginWork.old'; import {completeWork} from './ReactFiberCompleteWork.old'; import {unwindWork, unwindInterruptedWork} from './ReactFiberUnwindWork.old'; @@ -390,10 +390,7 @@ export function getCurrentTime() { return now(); } -export function requestUpdateLane( - fiber: Fiber, - suspenseConfig: SuspenseConfig | null, -): Lane { +export function requestUpdateLane(fiber: Fiber): Lane { // Special cases const mode = fiber.mode; if ((mode & BlockingMode) === NoMode) { @@ -437,10 +434,8 @@ export function requestUpdateLane( currentEventWipLanes = workInProgressRootIncludedLanes; } - if (suspenseConfig !== null) { - // Use the size of the timeout as a heuristic to prioritize shorter - // transitions over longer ones. - // TODO: This will coerce numbers larger than 31 bits to 0. + const isTransition = requestCurrentTransition() !== NoTransition; + if (isTransition) { if (currentEventPendingLanes !== NoLanes) { currentEventPendingLanes = mostRecentlyUpdatedRoot !== null diff --git a/packages/react-reconciler/src/ReactInternalTypes.js b/packages/react-reconciler/src/ReactInternalTypes.js index 51cce04255b65..e58a8e1a80f6b 100644 --- a/packages/react-reconciler/src/ReactInternalTypes.js +++ b/packages/react-reconciler/src/ReactInternalTypes.js @@ -27,7 +27,7 @@ import type {RootTag} from './ReactRootTags'; import type {TimeoutHandle, NoTimeout} from './ReactFiberHostConfig'; import type {Wakeable} from 'shared/ReactTypes'; import type {Interaction} from 'scheduler/src/Tracing'; -import type {SuspenseConfig, TimeoutConfig} from './ReactFiberSuspenseConfig'; +import type {SuspenseConfig, TimeoutConfig} from './ReactFiberTransition'; export type ReactPriorityLevel = 99 | 98 | 97 | 96 | 95 | 90; diff --git a/packages/react/src/ReactBatchConfig.js b/packages/react/src/ReactBatchConfig.js index b4aa8b927fde7..7e16239671528 100644 --- a/packages/react/src/ReactBatchConfig.js +++ b/packages/react/src/ReactBatchConfig.js @@ -7,17 +7,21 @@ * @flow */ -import type {SuspenseConfig} from 'react-reconciler/src/ReactFiberSuspenseConfig'; +import type {SuspenseConfig} from 'react-reconciler/src/ReactFiberTransition'; import ReactCurrentBatchConfig from './ReactCurrentBatchConfig'; -// Within the scope of the callback, mark all updates as being allowed to suspend. +// This is a copy of startTransition, except if null or undefined is passed, +// then updates inside the scope are opted-out of the outer transition scope. +// TODO: Deprecated. Remove in favor of startTransition. Figure out how scopes +// should nest, and whether we need an API to opt-out nested scopes. export function withSuspenseConfig(scope: () => void, config?: SuspenseConfig) { - const previousConfig = ReactCurrentBatchConfig.suspense; - ReactCurrentBatchConfig.suspense = config === undefined ? null : config; + const prevTransition = ReactCurrentBatchConfig.transition; + ReactCurrentBatchConfig.transition = + config === undefined || config === null ? 0 : 1; try { scope(); } finally { - ReactCurrentBatchConfig.suspense = previousConfig; + ReactCurrentBatchConfig.transition = prevTransition; } } diff --git a/packages/react/src/ReactCurrentBatchConfig.js b/packages/react/src/ReactCurrentBatchConfig.js index 7fc43dd3b7adc..9ba4a4c9c2c23 100644 --- a/packages/react/src/ReactCurrentBatchConfig.js +++ b/packages/react/src/ReactCurrentBatchConfig.js @@ -7,14 +7,12 @@ * @flow */ -import type {SuspenseConfig} from 'react-reconciler/src/ReactFiberSuspenseConfig'; - /** * Keeps track of the current batch's configuration such as how long an update * should suspend for if it needs to. */ const ReactCurrentBatchConfig = { - suspense: (null: null | SuspenseConfig), + transition: (0: number), }; export default ReactCurrentBatchConfig; diff --git a/packages/react/src/ReactStartTransition.js b/packages/react/src/ReactStartTransition.js index d17f083c473c7..afe1d2d282d55 100644 --- a/packages/react/src/ReactStartTransition.js +++ b/packages/react/src/ReactStartTransition.js @@ -9,16 +9,12 @@ import ReactCurrentBatchConfig from './ReactCurrentBatchConfig'; -// Default to an arbitrarily large timeout. Effectively, this is infinite. The -// eventual goal is to never timeout when refreshing already visible content. -const IndefiniteTimeoutConfig = {timeoutMs: 100000}; - export function startTransition(scope: () => void) { - const previousConfig = ReactCurrentBatchConfig.suspense; - ReactCurrentBatchConfig.suspense = IndefiniteTimeoutConfig; + const prevTransition = ReactCurrentBatchConfig.transition; + ReactCurrentBatchConfig.transition = 1; try { scope(); } finally { - ReactCurrentBatchConfig.suspense = previousConfig; + ReactCurrentBatchConfig.transition = prevTransition; } }