@samitouri / QOS-React-2 / commits / 92fcd46cc7

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.

Andrew Clark committed Aug 28, 2020 at 12:52 UTC 92fcd46cc79bbf45df4ce86b0678dcef3b91078d
15 files changed +80 -108
packages/react-debug-tools/src/ReactDebugHooks.js
+1 -1
@@ -20,7 +20,7 @@ import type {
20 } from 'react-reconciler/src/ReactInternalTypes';
21 import type {OpaqueIDType} from 'react-reconciler/src/ReactFiberHostConfig';
22
23 -import type {SuspenseConfig} from 'react-reconciler/src/ReactFiberSuspenseConfig';
23 +import type {SuspenseConfig} from 'react-reconciler/src/ReactFiberTransition';
24 import {NoMode} from 'react-reconciler/src/ReactTypeOfMode';
25
26 import ErrorStackParser from 'error-stack-parser';
packages/react-dom/src/server/ReactPartialRendererHooks.js
+1 -1
@@ -15,7 +15,7 @@ import type {
15 MutableSourceSubscribeFn,
16 ReactContext,
17 } from 'shared/ReactTypes';
18 -import type {SuspenseConfig} from 'react-reconciler/src/ReactFiberSuspenseConfig';
18 +import type {SuspenseConfig} from 'react-reconciler/src/ReactFiberTransition';
19 import type PartialRenderer from './ReactPartialRenderer';
20
21 import {validateContextBounds} from './ReactPartialRendererContext';
packages/react-reconciler/src/ReactFiberClassComponent.new.js
+3 -7
@@ -56,7 +56,6 @@ import {
56 requestUpdateLane,
57 scheduleUpdateOnFiber,
58 } from './ReactFiberWorkLoop.new';
59 -import {requestCurrentSuspenseConfig} from './ReactFiberSuspenseConfig';
59 import {logForceUpdateScheduled, logStateUpdateScheduled} from './DebugTracing';
60
61 import {disableLogs, reenableLogs} from 'shared/ConsolePatchingDev';
@@ -196,8 +195,7 @@ const classComponentUpdater = {
195 enqueueSetState(inst, payload, callback) {
196 const fiber = getInstance(inst);
197 const eventTime = requestEventTime();
199 - const suspenseConfig = requestCurrentSuspenseConfig();
200 - const lane = requestUpdateLane(fiber, suspenseConfig);
198 + const lane = requestUpdateLane(fiber);
199
200 const update = createUpdate(eventTime, lane);
201 update.payload = payload;
@@ -227,8 +225,7 @@ const classComponentUpdater = {
225 enqueueReplaceState(inst, payload, callback) {
226 const fiber = getInstance(inst);
227 const eventTime = requestEventTime();
230 - const suspenseConfig = requestCurrentSuspenseConfig();
231 - const lane = requestUpdateLane(fiber, suspenseConfig);
228 + const lane = requestUpdateLane(fiber);
229
230 const update = createUpdate(eventTime, lane);
231 update.tag = ReplaceState;
@@ -260,8 +257,7 @@ const classComponentUpdater = {
257 enqueueForceUpdate(inst, callback) {
258 const fiber = getInstance(inst);
259 const eventTime = requestEventTime();
263 - const suspenseConfig = requestCurrentSuspenseConfig();
264 - const lane = requestUpdateLane(fiber, suspenseConfig);
260 + const lane = requestUpdateLane(fiber);
261
262 const update = createUpdate(eventTime, lane);
263 update.tag = ForceUpdate;
packages/react-reconciler/src/ReactFiberClassComponent.old.js
+3 -7
@@ -56,7 +56,6 @@ import {
56 requestUpdateLane,
57 scheduleUpdateOnFiber,
58 } from './ReactFiberWorkLoop.old';
59 -import {requestCurrentSuspenseConfig} from './ReactFiberSuspenseConfig';
59 import {logForceUpdateScheduled, logStateUpdateScheduled} from './DebugTracing';
60
61 import {disableLogs, reenableLogs} from 'shared/ConsolePatchingDev';
@@ -196,8 +195,7 @@ const classComponentUpdater = {
195 enqueueSetState(inst, payload, callback) {
196 const fiber = getInstance(inst);
197 const eventTime = requestEventTime();
199 - const suspenseConfig = requestCurrentSuspenseConfig();
200 - const lane = requestUpdateLane(fiber, suspenseConfig);
198 + const lane = requestUpdateLane(fiber);
199
200 const update = createUpdate(eventTime, lane);
201 update.payload = payload;
@@ -227,8 +225,7 @@ const classComponentUpdater = {
225 enqueueReplaceState(inst, payload, callback) {
226 const fiber = getInstance(inst);
227 const eventTime = requestEventTime();
230 - const suspenseConfig = requestCurrentSuspenseConfig();
231 - const lane = requestUpdateLane(fiber, suspenseConfig);
228 + const lane = requestUpdateLane(fiber);
229
230 const update = createUpdate(eventTime, lane);
231 update.tag = ReplaceState;
@@ -260,8 +257,7 @@ const classComponentUpdater = {
257 enqueueForceUpdate(inst, callback) {
258 const fiber = getInstance(inst);
259 const eventTime = requestEventTime();
263 - const suspenseConfig = requestCurrentSuspenseConfig();
264 - const lane = requestUpdateLane(fiber, suspenseConfig);
260 + const lane = requestUpdateLane(fiber);
261
262 const update = createUpdate(eventTime, lane);
263 update.tag = ForceUpdate;
packages/react-reconciler/src/ReactFiberHooks.new.js
+19 -23
@@ -16,7 +16,7 @@ import type {
16 import type {Fiber, Dispatcher} from './ReactInternalTypes';
17 import type {Lanes, Lane} from './ReactFiberLane';
18 import type {HookEffectTag} from './ReactHookEffectTags';
19 -import type {SuspenseConfig} from './ReactFiberSuspenseConfig';
19 +import type {SuspenseConfig} from './ReactFiberTransition';
20 import type {ReactPriorityLevel} from './ReactInternalTypes';
21 import type {FiberRoot} from './ReactInternalTypes';
22 import type {OpaqueIDType} from './ReactFiberHostConfig';
@@ -70,7 +70,6 @@ import invariant from 'shared/invariant';
70 import getComponentName from 'shared/getComponentName';
71 import is from 'shared/objectIs';
72 import {markWorkInProgressReceivedUpdate} from './ReactFiberBeginWork.new';
73 -import {requestCurrentSuspenseConfig} from './ReactFiberSuspenseConfig';
73 import {
74 UserBlockingPriority,
75 NormalPriority,
@@ -1003,8 +1002,7 @@ function useMutableSource<Source, Snapshot>(
1002 if (!is(snapshot, maybeNewSnapshot)) {
1003 setSnapshot(maybeNewSnapshot);
1004
1006 - const suspenseConfig = requestCurrentSuspenseConfig();
1007 - const lane = requestUpdateLane(fiber, suspenseConfig);
1005 + const lane = requestUpdateLane(fiber);
1006 markRootMutableRead(root, lane);
1007 }
1008 // If the source mutated between render and now,
@@ -1024,8 +1022,7 @@ function useMutableSource<Source, Snapshot>(
1022 latestSetSnapshot(latestGetSnapshot(source._source));
1023
1024 // Record a pending mutable source update with the same expiration time.
1027 - const suspenseConfig = requestCurrentSuspenseConfig();
1028 - const lane = requestUpdateLane(fiber, suspenseConfig);
1025 + const lane = requestUpdateLane(fiber);
1026
1027 markRootMutableRead(root, lane);
1028 } catch (error) {
@@ -1441,12 +1438,12 @@ function mountDeferredValue<T>(
1438 ): T {
1439 const [prevValue, setValue] = mountState(value);
1440 mountEffect(() => {
1444 - const previousConfig = ReactCurrentBatchConfig.suspense;
1445 - ReactCurrentBatchConfig.suspense = config === undefined ? null : config;
1441 + const prevTransition = ReactCurrentBatchConfig.transition;
1442 + ReactCurrentBatchConfig.transition = 1;
1443 try {
1444 setValue(value);
1445 } finally {
1449 - ReactCurrentBatchConfig.suspense = previousConfig;
1446 + ReactCurrentBatchConfig.transition = prevTransition;
1447 }
1448 }, [value, config]);
1449 return prevValue;
@@ -1458,12 +1455,12 @@ function updateDeferredValue<T>(
1455 ): T {
1456 const [prevValue, setValue] = updateState(value);
1457 updateEffect(() => {
1461 - const previousConfig = ReactCurrentBatchConfig.suspense;
1462 - ReactCurrentBatchConfig.suspense = config === undefined ? null : config;
1458 + const prevTransition = ReactCurrentBatchConfig.transition;
1459 + ReactCurrentBatchConfig.transition = 1;
1460 try {
1461 setValue(value);
1462 } finally {
1466 - ReactCurrentBatchConfig.suspense = previousConfig;
1463 + ReactCurrentBatchConfig.transition = prevTransition;
1464 }
1465 }, [value, config]);
1466 return prevValue;
@@ -1475,12 +1472,12 @@ function rerenderDeferredValue<T>(
1472 ): T {
1473 const [prevValue, setValue] = rerenderState(value);
1474 updateEffect(() => {
1478 - const previousConfig = ReactCurrentBatchConfig.suspense;
1479 - ReactCurrentBatchConfig.suspense = config === undefined ? null : config;
1475 + const prevTransition = ReactCurrentBatchConfig.transition;
1476 + ReactCurrentBatchConfig.transition = 1;
1477 try {
1478 setValue(value);
1479 } finally {
1483 - ReactCurrentBatchConfig.suspense = previousConfig;
1480 + ReactCurrentBatchConfig.transition = prevTransition;
1481 }
1482 }, [value, config]);
1483 return prevValue;
@@ -1509,8 +1506,8 @@ function startTransition(setPending, config, callback) {
1506 runWithPriority(
1507 priorityLevel > NormalPriority ? NormalPriority : priorityLevel,
1508 () => {
1512 - const previousConfig = ReactCurrentBatchConfig.suspense;
1513 - ReactCurrentBatchConfig.suspense = config === undefined ? null : config;
1509 + const prevTransition = ReactCurrentBatchConfig.transition;
1510 + ReactCurrentBatchConfig.transition = 1;
1511 try {
1512 setPending(false);
1513 callback();
@@ -1518,7 +1515,7 @@ function startTransition(setPending, config, callback) {
1515 if (decoupleUpdatePriorityFromScheduler) {
1516 setCurrentUpdateLanePriority(previousLanePriority);
1517 }
1521 - ReactCurrentBatchConfig.suspense = previousConfig;
1518 + ReactCurrentBatchConfig.transition = prevTransition;
1519 }
1520 },
1521 );
@@ -1535,13 +1532,13 @@ function startTransition(setPending, config, callback) {
1532 runWithPriority(
1533 priorityLevel > NormalPriority ? NormalPriority : priorityLevel,
1534 () => {
1538 - const previousConfig = ReactCurrentBatchConfig.suspense;
1539 - ReactCurrentBatchConfig.suspense = config === undefined ? null : config;
1535 + const prevTransition = ReactCurrentBatchConfig.transition;
1536 + ReactCurrentBatchConfig.transition = 1;
1537 try {
1538 setPending(false);
1539 callback();
1540 } finally {
1544 - ReactCurrentBatchConfig.suspense = previousConfig;
1541 + ReactCurrentBatchConfig.transition = prevTransition;
1542 }
1543 },
1544 );
@@ -1685,8 +1682,7 @@ function dispatchAction<S, A>(
1682 }
1683
1684 const eventTime = requestEventTime();
1688 - const suspenseConfig = requestCurrentSuspenseConfig();
1689 - const lane = requestUpdateLane(fiber, suspenseConfig);
1685 + const lane = requestUpdateLane(fiber);
1686
1687 const update: Update<S, A> = {
1688 lane,
packages/react-reconciler/src/ReactFiberHooks.old.js
+19 -23
@@ -16,7 +16,7 @@ import type {
16 import type {Fiber, Dispatcher} from './ReactInternalTypes';
17 import type {Lanes, Lane} from './ReactFiberLane';
18 import type {HookEffectTag} from './ReactHookEffectTags';
19 -import type {SuspenseConfig} from './ReactFiberSuspenseConfig';
19 +import type {SuspenseConfig} from './ReactFiberTransition';
20 import type {ReactPriorityLevel} from './ReactInternalTypes';
21 import type {FiberRoot} from './ReactInternalTypes';
22 import type {OpaqueIDType} from './ReactFiberHostConfig';
@@ -69,7 +69,6 @@ import invariant from 'shared/invariant';
69 import getComponentName from 'shared/getComponentName';
70 import is from 'shared/objectIs';
71 import {markWorkInProgressReceivedUpdate} from './ReactFiberBeginWork.old';
72 -import {requestCurrentSuspenseConfig} from './ReactFiberSuspenseConfig';
72 import {
73 UserBlockingPriority,
74 NormalPriority,
@@ -1002,8 +1001,7 @@ function useMutableSource<Source, Snapshot>(
1001 if (!is(snapshot, maybeNewSnapshot)) {
1002 setSnapshot(maybeNewSnapshot);
1003
1005 - const suspenseConfig = requestCurrentSuspenseConfig();
1006 - const lane = requestUpdateLane(fiber, suspenseConfig);
1004 + const lane = requestUpdateLane(fiber);
1005 markRootMutableRead(root, lane);
1006 }
1007 // If the source mutated between render and now,
@@ -1023,8 +1021,7 @@ function useMutableSource<Source, Snapshot>(
1021 latestSetSnapshot(latestGetSnapshot(source._source));
1022
1023 // Record a pending mutable source update with the same expiration time.
1026 - const suspenseConfig = requestCurrentSuspenseConfig();
1027 - const lane = requestUpdateLane(fiber, suspenseConfig);
1024 + const lane = requestUpdateLane(fiber);
1025
1026 markRootMutableRead(root, lane);
1027 } catch (error) {
@@ -1440,12 +1437,12 @@ function mountDeferredValue<T>(
1437 ): T {
1438 const [prevValue, setValue] = mountState(value);
1439 mountEffect(() => {
1443 - const previousConfig = ReactCurrentBatchConfig.suspense;
1444 - ReactCurrentBatchConfig.suspense = config === undefined ? null : config;
1440 + const prevTransition = ReactCurrentBatchConfig.transition;
1441 + ReactCurrentBatchConfig.transition = 1;
1442 try {
1443 setValue(value);
1444 } finally {
1448 - ReactCurrentBatchConfig.suspense = previousConfig;
1445 + ReactCurrentBatchConfig.transition = prevTransition;
1446 }
1447 }, [value, config]);
1448 return prevValue;
@@ -1457,12 +1454,12 @@ function updateDeferredValue<T>(
1454 ): T {
1455 const [prevValue, setValue] = updateState(value);
1456 updateEffect(() => {
1460 - const previousConfig = ReactCurrentBatchConfig.suspense;
1461 - ReactCurrentBatchConfig.suspense = config === undefined ? null : config;
1457 + const prevTransition = ReactCurrentBatchConfig.transition;
1458 + ReactCurrentBatchConfig.transition = 1;
1459 try {
1460 setValue(value);
1461 } finally {
1465 - ReactCurrentBatchConfig.suspense = previousConfig;
1462 + ReactCurrentBatchConfig.transition = prevTransition;
1463 }
1464 }, [value, config]);
1465 return prevValue;
@@ -1474,12 +1471,12 @@ function rerenderDeferredValue<T>(
1471 ): T {
1472 const [prevValue, setValue] = rerenderState(value);
1473 updateEffect(() => {
1477 - const previousConfig = ReactCurrentBatchConfig.suspense;
1478 - ReactCurrentBatchConfig.suspense = config === undefined ? null : config;
1474 + const prevTransition = ReactCurrentBatchConfig.transition;
1475 + ReactCurrentBatchConfig.transition = 1;
1476 try {
1477 setValue(value);
1478 } finally {
1482 - ReactCurrentBatchConfig.suspense = previousConfig;
1479 + ReactCurrentBatchConfig.transition = prevTransition;
1480 }
1481 }, [value, config]);
1482 return prevValue;
@@ -1508,8 +1505,8 @@ function startTransition(setPending, config, callback) {
1505 runWithPriority(
1506 priorityLevel > NormalPriority ? NormalPriority : priorityLevel,
1507 () => {
1511 - const previousConfig = ReactCurrentBatchConfig.suspense;
1512 - ReactCurrentBatchConfig.suspense = config === undefined ? null : config;
1508 + const prevTransition = ReactCurrentBatchConfig.transition;
1509 + ReactCurrentBatchConfig.transition = 1;
1510 try {
1511 setPending(false);
1512 callback();
@@ -1517,7 +1514,7 @@ function startTransition(setPending, config, callback) {
1514 if (decoupleUpdatePriorityFromScheduler) {
1515 setCurrentUpdateLanePriority(previousLanePriority);
1516 }
1520 - ReactCurrentBatchConfig.suspense = previousConfig;
1517 + ReactCurrentBatchConfig.transition = prevTransition;
1518 }
1519 },
1520 );
@@ -1534,13 +1531,13 @@ function startTransition(setPending, config, callback) {
1531 runWithPriority(
1532 priorityLevel > NormalPriority ? NormalPriority : priorityLevel,
1533 () => {
1537 - const previousConfig = ReactCurrentBatchConfig.suspense;
1538 - ReactCurrentBatchConfig.suspense = config === undefined ? null : config;
1534 + const prevTransition = ReactCurrentBatchConfig.transition;
1535 + ReactCurrentBatchConfig.transition = 1;
1536 try {
1537 setPending(false);
1538 callback();
1539 } finally {
1543 - ReactCurrentBatchConfig.suspense = previousConfig;
1540 + ReactCurrentBatchConfig.transition = prevTransition;
1541 }
1542 },
1543 );
@@ -1683,8 +1680,7 @@ function dispatchAction<S, A>(
1680 }
1681
1682 const eventTime = requestEventTime();
1686 - const suspenseConfig = requestCurrentSuspenseConfig();
1687 - const lane = requestUpdateLane(fiber, suspenseConfig);
1683 + const lane = requestUpdateLane(fiber);
1684
1685 const update: Update<S, A> = {
1686 lane,
packages/react-reconciler/src/ReactFiberReconciler.new.js
+2 -4
@@ -83,7 +83,6 @@ import {
83 getCurrentUpdateLanePriority,
84 setCurrentUpdateLanePriority,
85 } from './ReactFiberLane';
86 -import {requestCurrentSuspenseConfig} from './ReactFiberSuspenseConfig';
86 import {
87 scheduleRefresh,
88 scheduleRoot,
@@ -266,8 +265,7 @@ export function updateContainer(
265 warnIfNotScopedWithMatchingAct(current);
266 }
267 }
269 - const suspenseConfig = requestCurrentSuspenseConfig();
270 - const lane = requestUpdateLane(current, suspenseConfig);
268 + const lane = requestUpdateLane(current);
269
270 if (enableSchedulingProfiler) {
271 markRenderScheduled(lane);
@@ -427,7 +425,7 @@ export function attemptHydrationAtCurrentPriority(fiber: Fiber): void {
425 return;
426 }
427 const eventTime = requestEventTime();
430 - const lane = requestUpdateLane(fiber, null);
428 + const lane = requestUpdateLane(fiber);
429 scheduleUpdateOnFiber(fiber, lane, eventTime);
430 markRetryLaneIfNotHydrated(fiber, lane);
431 }
packages/react-reconciler/src/ReactFiberReconciler.old.js
+2 -4
@@ -83,7 +83,6 @@ import {
83 getCurrentUpdateLanePriority,
84 setCurrentUpdateLanePriority,
85 } from './ReactFiberLane';
86 -import {requestCurrentSuspenseConfig} from './ReactFiberSuspenseConfig';
86 import {
87 scheduleRefresh,
88 scheduleRoot,
@@ -266,8 +265,7 @@ export function updateContainer(
265 warnIfNotScopedWithMatchingAct(current);
266 }
267 }
269 - const suspenseConfig = requestCurrentSuspenseConfig();
270 - const lane = requestUpdateLane(current, suspenseConfig);
268 + const lane = requestUpdateLane(current);
269
270 if (enableSchedulingProfiler) {
271 markRenderScheduled(lane);
@@ -427,7 +425,7 @@ export function attemptHydrationAtCurrentPriority(fiber: Fiber): void {
425 return;
426 }
427 const eventTime = requestEventTime();
430 - const lane = requestUpdateLane(fiber, null);
428 + const lane = requestUpdateLane(fiber);
429 scheduleUpdateOnFiber(fiber, lane, eventTime);
430 markRetryLaneIfNotHydrated(fiber, lane);
431 }
packages/react-reconciler/src/ReactFiberTransition.js renamed
+8 -4
@@ -9,18 +9,22 @@
9
10 import ReactSharedInternals from 'shared/ReactSharedInternals';
11
12 -const {ReactCurrentBatchConfig} = ReactSharedInternals;
13 -
12 +// Deprecated
13 export type SuspenseConfig = {|
14 timeoutMs: number,
15 busyDelayMs?: number,
16 busyMinDurationMs?: number,
17 |};
18
19 +// Deprecated
20 export type TimeoutConfig = {|
21 timeoutMs: number,
22 |};
23
24 -export function requestCurrentSuspenseConfig(): null | SuspenseConfig {
25 - return ReactCurrentBatchConfig.suspense;
24 +const {ReactCurrentBatchConfig} = ReactSharedInternals;
25 +
26 +export const NoTransition = 0;
27 +
28 +export function requestCurrentTransition(): number {
29 + return ReactCurrentBatchConfig.transition;
30 }
packages/react-reconciler/src/ReactFiberWorkLoop.new.js
+4 -9
@@ -12,7 +12,6 @@ import type {Fiber, FiberRoot} from './ReactInternalTypes';
12 import type {Lanes, Lane} from './ReactFiberLane';
13 import type {ReactPriorityLevel} from './ReactInternalTypes';
14 import type {Interaction} from 'scheduler/src/Tracing';
15 -import type {SuspenseConfig} from './ReactFiberSuspenseConfig';
15 import type {SuspenseState} from './ReactFiberSuspenseComponent.new';
16 import type {StackCursor} from './ReactFiberStack.new';
17 import type {FunctionComponentUpdateQueue} from './ReactFiberHooks.new';
@@ -188,6 +187,7 @@ import {
187 schedulerPriorityToLanePriority,
188 lanePriorityToSchedulerPriority,
189 } from './ReactFiberLane';
190 +import {requestCurrentTransition, NoTransition} from './ReactFiberTransition';
191 import {beginWork as originalBeginWork} from './ReactFiberBeginWork.new';
192 import {completeWork} from './ReactFiberCompleteWork.new';
193 import {unwindWork, unwindInterruptedWork} from './ReactFiberUnwindWork.new';
@@ -402,10 +402,7 @@ export function getCurrentTime() {
402 return now();
403 }
404
405 -export function requestUpdateLane(
406 - fiber: Fiber,
407 - suspenseConfig: SuspenseConfig | null,
408 -): Lane {
405 +export function requestUpdateLane(fiber: Fiber): Lane {
406 // Special cases
407 const mode = fiber.mode;
408 if ((mode & BlockingMode) === NoMode) {
@@ -449,10 +446,8 @@ export function requestUpdateLane(
446 currentEventWipLanes = workInProgressRootIncludedLanes;
447 }
448
452 - if (suspenseConfig !== null) {
453 - // Use the size of the timeout as a heuristic to prioritize shorter
454 - // transitions over longer ones.
455 - // TODO: This will coerce numbers larger than 31 bits to 0.
449 + const isTransition = requestCurrentTransition() !== NoTransition;
450 + if (isTransition) {
451 if (currentEventPendingLanes !== NoLanes) {
452 currentEventPendingLanes =
453 mostRecentlyUpdatedRoot !== null
packages/react-reconciler/src/ReactFiberWorkLoop.old.js
+4 -9
@@ -12,7 +12,6 @@ import type {Fiber, FiberRoot} from './ReactInternalTypes';
12 import type {Lanes, Lane} from './ReactFiberLane';
13 import type {ReactPriorityLevel} from './ReactInternalTypes';
14 import type {Interaction} from 'scheduler/src/Tracing';
15 -import type {SuspenseConfig} from './ReactFiberSuspenseConfig';
15 import type {SuspenseState} from './ReactFiberSuspenseComponent.old';
16 import type {Effect as HookEffect} from './ReactFiberHooks.old';
17 import type {StackCursor} from './ReactFiberStack.old';
@@ -174,6 +173,7 @@ import {
173 schedulerPriorityToLanePriority,
174 lanePriorityToSchedulerPriority,
175 } from './ReactFiberLane';
176 +import {requestCurrentTransition, NoTransition} from './ReactFiberTransition';
177 import {beginWork as originalBeginWork} from './ReactFiberBeginWork.old';
178 import {completeWork} from './ReactFiberCompleteWork.old';
179 import {unwindWork, unwindInterruptedWork} from './ReactFiberUnwindWork.old';
@@ -390,10 +390,7 @@ export function getCurrentTime() {
390 return now();
391 }
392
393 -export function requestUpdateLane(
394 - fiber: Fiber,
395 - suspenseConfig: SuspenseConfig | null,
396 -): Lane {
393 +export function requestUpdateLane(fiber: Fiber): Lane {
394 // Special cases
395 const mode = fiber.mode;
396 if ((mode & BlockingMode) === NoMode) {
@@ -437,10 +434,8 @@ export function requestUpdateLane(
434 currentEventWipLanes = workInProgressRootIncludedLanes;
435 }
436
440 - if (suspenseConfig !== null) {
441 - // Use the size of the timeout as a heuristic to prioritize shorter
442 - // transitions over longer ones.
443 - // TODO: This will coerce numbers larger than 31 bits to 0.
437 + const isTransition = requestCurrentTransition() !== NoTransition;
438 + if (isTransition) {
439 if (currentEventPendingLanes !== NoLanes) {
440 currentEventPendingLanes =
441 mostRecentlyUpdatedRoot !== null
packages/react-reconciler/src/ReactInternalTypes.js
+1 -1
@@ -27,7 +27,7 @@ import type {RootTag} from './ReactRootTags';
27 import type {TimeoutHandle, NoTimeout} from './ReactFiberHostConfig';
28 import type {Wakeable} from 'shared/ReactTypes';
29 import type {Interaction} from 'scheduler/src/Tracing';
30 -import type {SuspenseConfig, TimeoutConfig} from './ReactFiberSuspenseConfig';
30 +import type {SuspenseConfig, TimeoutConfig} from './ReactFiberTransition';
31
32 export type ReactPriorityLevel = 99 | 98 | 97 | 96 | 95 | 90;
33
packages/react/src/ReactBatchConfig.js
+9 -5
@@ -7,17 +7,21 @@
7 * @flow
8 */
9
10 -import type {SuspenseConfig} from 'react-reconciler/src/ReactFiberSuspenseConfig';
10 +import type {SuspenseConfig} from 'react-reconciler/src/ReactFiberTransition';
11
12 import ReactCurrentBatchConfig from './ReactCurrentBatchConfig';
13
14 -// Within the scope of the callback, mark all updates as being allowed to suspend.
14 +// This is a copy of startTransition, except if null or undefined is passed,
15 +// then updates inside the scope are opted-out of the outer transition scope.
16 +// TODO: Deprecated. Remove in favor of startTransition. Figure out how scopes
17 +// should nest, and whether we need an API to opt-out nested scopes.
18 export function withSuspenseConfig(scope: () => void, config?: SuspenseConfig) {
16 - const previousConfig = ReactCurrentBatchConfig.suspense;
17 - ReactCurrentBatchConfig.suspense = config === undefined ? null : config;
19 + const prevTransition = ReactCurrentBatchConfig.transition;
20 + ReactCurrentBatchConfig.transition =
21 + config === undefined || config === null ? 0 : 1;
22 try {
23 scope();
24 } finally {
21 - ReactCurrentBatchConfig.suspense = previousConfig;
25 + ReactCurrentBatchConfig.transition = prevTransition;
26 }
27 }
packages/react/src/ReactCurrentBatchConfig.js
+1 -3
@@ -7,14 +7,12 @@
7 * @flow
8 */
9
10 -import type {SuspenseConfig} from 'react-reconciler/src/ReactFiberSuspenseConfig';
11 -
10 /**
11 * Keeps track of the current batch's configuration such as how long an update
12 * should suspend for if it needs to.
13 */
14 const ReactCurrentBatchConfig = {
17 - suspense: (null: null | SuspenseConfig),
15 + transition: (0: number),
16 };
17
18 export default ReactCurrentBatchConfig;
packages/react/src/ReactStartTransition.js
+3 -7
@@ -9,16 +9,12 @@
9
10 import ReactCurrentBatchConfig from './ReactCurrentBatchConfig';
11
12 -// Default to an arbitrarily large timeout. Effectively, this is infinite. The
13 -// eventual goal is to never timeout when refreshing already visible content.
14 -const IndefiniteTimeoutConfig = {timeoutMs: 100000};
15 -
12 export function startTransition(scope: () => void) {
17 - const previousConfig = ReactCurrentBatchConfig.suspense;
18 - ReactCurrentBatchConfig.suspense = IndefiniteTimeoutConfig;
13 + const prevTransition = ReactCurrentBatchConfig.transition;
14 + ReactCurrentBatchConfig.transition = 1;
15 try {
16 scope();
17 } finally {
22 - ReactCurrentBatchConfig.suspense = previousConfig;
18 + ReactCurrentBatchConfig.transition = prevTransition;
19 }
20 }