Skip to content

Commit

Permalink
Get legacy ReactCurrentActQueue checks
Browse files Browse the repository at this point in the history
  • Loading branch information
sebmarkbage committed Apr 3, 2024
1 parent 477cf7e commit 8d5cba2
Showing 1 changed file with 20 additions and 7 deletions.
27 changes: 20 additions & 7 deletions packages/react/src/ReactAct.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import type {RendererTask} from './ReactCurrentActQueue';
import ReactCurrentActQueue from './ReactCurrentActQueue';
import queueMacrotask from 'shared/enqueueTask';

import {disableLegacyMode} from 'shared/ReactFeatureFlags';

// `act` calls can be nested, so we track the depth. This represents the
// number of `act` scopes on the stack.
let actScopeDepth = 0;
Expand All @@ -38,7 +40,9 @@ export function act<T>(callback: () => T | Thenable<T>): Thenable<T> {
// `act` calls can be nested.
//
// If we're already inside an `act` scope, reuse the existing queue.
const prevIsBatchingLegacy = ReactCurrentActQueue.isBatchingLegacy;
const prevIsBatchingLegacy = !disableLegacyMode
? ReactCurrentActQueue.isBatchingLegacy
: false;
const prevActQueue = ReactCurrentActQueue.current;
const prevActScopeDepth = actScopeDepth;
actScopeDepth++;
Expand All @@ -48,7 +52,9 @@ export function act<T>(callback: () => T | Thenable<T>): Thenable<T> {
// set to `true` while the given callback is executed, not for updates
// triggered during an async event, because this is how the legacy
// implementation of `act` behaved.
ReactCurrentActQueue.isBatchingLegacy = true;
if (!disableLegacyMode) {
ReactCurrentActQueue.isBatchingLegacy = true;
}

let result;
// This tracks whether the `act` call is awaited. In certain cases, not
Expand All @@ -58,10 +64,13 @@ export function act<T>(callback: () => T | Thenable<T>): Thenable<T> {
// Reset this to `false` right before entering the React work loop. The
// only place we ever read this fields is just below, right after running
// the callback. So we don't need to reset after the callback runs.
ReactCurrentActQueue.didScheduleLegacyUpdate = false;
if (!disableLegacyMode) {
ReactCurrentActQueue.didScheduleLegacyUpdate = false;
}
result = callback();
const didScheduleLegacyUpdate =
ReactCurrentActQueue.didScheduleLegacyUpdate;
const didScheduleLegacyUpdate = !disableLegacyMode
? ReactCurrentActQueue.didScheduleLegacyUpdate
: false;

// Replicate behavior of original `act` implementation in legacy mode,
// which flushed updates immediately after the scope function exits, even
Expand All @@ -73,7 +82,9 @@ export function act<T>(callback: () => T | Thenable<T>): Thenable<T> {
// one used to track `act` scopes. Why, you may be wondering? Because
// that's how it worked before version 18. Yes, it's confusing! We should
// delete legacy mode!!
ReactCurrentActQueue.isBatchingLegacy = prevIsBatchingLegacy;
if (!disableLegacyMode) {
ReactCurrentActQueue.isBatchingLegacy = prevIsBatchingLegacy;
}
} catch (error) {
// `isBatchingLegacy` gets reset using the regular stack, not the async
// one used to track `act` scopes. Why, you may be wondering? Because
Expand All @@ -82,7 +93,9 @@ export function act<T>(callback: () => T | Thenable<T>): Thenable<T> {
ReactCurrentActQueue.thrownErrors.push(error);
}
if (ReactCurrentActQueue.thrownErrors.length > 0) {
ReactCurrentActQueue.isBatchingLegacy = prevIsBatchingLegacy;
if (!disableLegacyMode) {
ReactCurrentActQueue.isBatchingLegacy = prevIsBatchingLegacy;
}
popActScope(prevActQueue, prevActScopeDepth);
const thrownError = aggregateErrors(ReactCurrentActQueue.thrownErrors);
ReactCurrentActQueue.thrownErrors.length = 0;
Expand Down

0 comments on commit 8d5cba2

Please sign in to comment.