From f5a0fc6b3a159dd15f8f9780440763e11431d0f2 Mon Sep 17 00:00:00 2001 From: Andrew Clark Date: Wed, 26 Aug 2020 20:10:21 -0500 Subject: [PATCH] Replace SuspenseConfig object with an integer 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; } }