diff --git a/fixtures/dom/src/index.test.js b/fixtures/dom/src/index.test.js
index ad10e99d36b7b..fe3ec883fa909 100644
--- a/fixtures/dom/src/index.test.js
+++ b/fixtures/dom/src/index.test.js
@@ -70,10 +70,7 @@ it('warns when using the wrong act version - test + dom: updates', () => {
TestRenderer.act(() => {
setCtr(1);
});
- }).toWarnDev([
- 'An update to Counter inside a test was not wrapped in act',
- "It looks like you're using the wrong act()",
- ]);
+ }).toWarnDev(["It looks like you're using the wrong act()"]);
});
it('warns when using the wrong act version - dom + test: .create()', () => {
@@ -109,10 +106,7 @@ it('warns when using the wrong act version - dom + test: updates', () => {
TestUtils.act(() => {
setCtr(1);
});
- }).toWarnDev([
- 'An update to Counter inside a test was not wrapped in act',
- "It looks like you're using the wrong act()",
- ]);
+ }).toWarnDev(["It looks like you're using the wrong act()"]);
});
const {Surface, Group, Shape} = ReactART;
@@ -158,3 +152,11 @@ it('does not warn when nesting react-act inside react-test-renderer', () => {
TestRenderer.create();
});
});
+
+it("doesn't warn if you use nested acts from different renderers", () => {
+ TestRenderer.act(() => {
+ TestUtils.act(() => {
+ TestRenderer.create();
+ });
+ });
+});
diff --git a/packages/react-art/src/ReactARTHostConfig.js b/packages/react-art/src/ReactARTHostConfig.js
index a351d261b5fa4..2a221f0e48976 100644
--- a/packages/react-art/src/ReactARTHostConfig.js
+++ b/packages/react-art/src/ReactARTHostConfig.js
@@ -347,7 +347,7 @@ export function shouldSetTextContent(type, props) {
export const isPrimaryRenderer = false;
// The ART renderer shouldn't trigger missing act() warnings
-export const shouldWarnUnactedUpdates = false;
+export const warnsIfNotActing = false;
export const supportsMutation = true;
diff --git a/packages/react-dom/src/client/ReactDOM.js b/packages/react-dom/src/client/ReactDOM.js
index 1db9e527efe19..8e84b320c7a5f 100644
--- a/packages/react-dom/src/client/ReactDOM.js
+++ b/packages/react-dom/src/client/ReactDOM.js
@@ -38,7 +38,7 @@ import {
findHostInstance,
findHostInstanceWithWarning,
flushPassiveEffects,
- ReactActingRendererSigil,
+ IsThisRendererActing,
} from 'react-reconciler/inline.dom';
import {createPortal as createPortalImpl} from 'shared/ReactPortal';
import {canUseDOM} from 'shared/ExecutionEnvironment';
@@ -817,7 +817,7 @@ const ReactDOM: Object = {
dispatchEvent,
runEventsInBatch,
flushPassiveEffects,
- ReactActingRendererSigil,
+ IsThisRendererActing,
],
},
};
diff --git a/packages/react-dom/src/client/ReactDOMHostConfig.js b/packages/react-dom/src/client/ReactDOMHostConfig.js
index ef223abf5213a..f76d77cb0ac3b 100644
--- a/packages/react-dom/src/client/ReactDOMHostConfig.js
+++ b/packages/react-dom/src/client/ReactDOMHostConfig.js
@@ -348,7 +348,7 @@ export function createTextInstance(
}
export const isPrimaryRenderer = true;
-export const shouldWarnUnactedUpdates = true;
+export const warnsIfNotActing = true;
// This initialization code may run even on server environments
// if a component just imports ReactDOM (e.g. for findDOMNode).
// Some environments might not have setTimeout or clearTimeout.
diff --git a/packages/react-dom/src/fire/ReactFire.js b/packages/react-dom/src/fire/ReactFire.js
index bb74931fdc3ef..5acb58187e539 100644
--- a/packages/react-dom/src/fire/ReactFire.js
+++ b/packages/react-dom/src/fire/ReactFire.js
@@ -43,7 +43,7 @@ import {
findHostInstance,
findHostInstanceWithWarning,
flushPassiveEffects,
- ReactActingRendererSigil,
+ IsThisRendererActing,
} from 'react-reconciler/inline.fire';
import {createPortal as createPortalImpl} from 'shared/ReactPortal';
import {canUseDOM} from 'shared/ExecutionEnvironment';
@@ -823,7 +823,7 @@ const ReactDOM: Object = {
dispatchEvent,
runEventsInBatch,
flushPassiveEffects,
- ReactActingRendererSigil,
+ IsThisRendererActing,
],
},
};
diff --git a/packages/react-dom/src/test-utils/ReactTestUtils.js b/packages/react-dom/src/test-utils/ReactTestUtils.js
index 5f4d96fa9632b..6c9a899ebce51 100644
--- a/packages/react-dom/src/test-utils/ReactTestUtils.js
+++ b/packages/react-dom/src/test-utils/ReactTestUtils.js
@@ -44,7 +44,7 @@ const [
runEventsInBatch,
/* eslint-disable no-unused-vars */
flushPassiveEffects,
- ReactActingRendererSigil,
+ IsThisRendererActing,
/* eslint-enable no-unused-vars */
] = ReactDOM.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Events;
diff --git a/packages/react-dom/src/test-utils/ReactTestUtilsAct.js b/packages/react-dom/src/test-utils/ReactTestUtilsAct.js
index c12f396795966..791d4878c13d7 100644
--- a/packages/react-dom/src/test-utils/ReactTestUtilsAct.js
+++ b/packages/react-dom/src/test-utils/ReactTestUtilsAct.js
@@ -33,12 +33,12 @@ const [
runEventsInBatch,
/* eslint-enable no-unused-vars */
flushPassiveEffects,
- ReactActingRendererSigil,
+ IsThisRendererActing,
] = ReactDOM.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.Events;
const batchedUpdates = ReactDOM.unstable_batchedUpdates;
-const {ReactCurrentActingRendererSigil} = ReactSharedInternals;
+const {IsSomeRendererActing} = ReactSharedInternals;
// this implementation should be exactly the same in
// ReactTestUtilsAct.js, ReactTestRendererAct.js, createReactNoop.js
@@ -86,17 +86,21 @@ let actingUpdatesScopeDepth = 0;
function act(callback: () => Thenable) {
let previousActingUpdatesScopeDepth = actingUpdatesScopeDepth;
- let previousActingUpdatesSigil;
+ let previousIsSomeRendererActing;
+ let previousIsThisRendererActing;
actingUpdatesScopeDepth++;
if (__DEV__) {
- previousActingUpdatesSigil = ReactCurrentActingRendererSigil.current;
- ReactCurrentActingRendererSigil.current = ReactActingRendererSigil;
+ previousIsSomeRendererActing = IsSomeRendererActing.current;
+ previousIsThisRendererActing = IsSomeRendererActing.current;
+ IsSomeRendererActing.current = true;
+ IsThisRendererActing.current = true;
}
function onDone() {
actingUpdatesScopeDepth--;
if (__DEV__) {
- ReactCurrentActingRendererSigil.current = previousActingUpdatesSigil;
+ IsSomeRendererActing.current = previousIsSomeRendererActing;
+ IsThisRendererActing.current = previousIsThisRendererActing;
if (actingUpdatesScopeDepth > previousActingUpdatesScopeDepth) {
// if it's _less than_ previousActingUpdatesScopeDepth, then we can assume the 'other' one has warned
warningWithoutStack(
diff --git a/packages/react-native-renderer/src/ReactFabricHostConfig.js b/packages/react-native-renderer/src/ReactFabricHostConfig.js
index 46561a0ef9fac..52a3966f2d715 100644
--- a/packages/react-native-renderer/src/ReactFabricHostConfig.js
+++ b/packages/react-native-renderer/src/ReactFabricHostConfig.js
@@ -352,7 +352,7 @@ export function shouldSetTextContent(type: string, props: Props): boolean {
export const isPrimaryRenderer = false;
// The Fabric renderer shouldn't trigger missing act() warnings
-export const shouldWarnUnactedUpdates = false;
+export const warnsIfNotActing = false;
export const scheduleTimeout = setTimeout;
export const cancelTimeout = clearTimeout;
diff --git a/packages/react-native-renderer/src/ReactNativeHostConfig.js b/packages/react-native-renderer/src/ReactNativeHostConfig.js
index 1f3cbea15a9a2..28d7317f3ff1f 100644
--- a/packages/react-native-renderer/src/ReactNativeHostConfig.js
+++ b/packages/react-native-renderer/src/ReactNativeHostConfig.js
@@ -247,7 +247,7 @@ export function resetAfterCommit(containerInfo: Container): void {
}
export const isPrimaryRenderer = true;
-export const shouldWarnUnactedUpdates = true;
+export const warnsIfNotActing = true;
export const scheduleTimeout = setTimeout;
export const cancelTimeout = clearTimeout;
diff --git a/packages/react-noop-renderer/src/createReactNoop.js b/packages/react-noop-renderer/src/createReactNoop.js
index f1d7fc419548d..4dcae01cbc076 100644
--- a/packages/react-noop-renderer/src/createReactNoop.js
+++ b/packages/react-noop-renderer/src/createReactNoop.js
@@ -65,7 +65,7 @@ type TextInstance = {|
|};
type HostContext = Object;
-const {ReactCurrentActingRendererSigil} = ReactSharedInternals;
+const {IsSomeRendererActing} = ReactSharedInternals;
const NO_CONTEXT = {};
const UPPERCASE_CONTEXT = {};
@@ -393,7 +393,7 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
now: Scheduler.unstable_now,
isPrimaryRenderer: true,
- shouldWarnUnactedUpdates: true,
+ warnsIfNotActing: true,
supportsHydration: false,
mountEventComponent(): void {
@@ -566,7 +566,7 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
const {
flushPassiveEffects,
batchedUpdates,
- ReactActingRendererSigil,
+ IsThisRendererActing,
} = NoopRenderer;
// this act() implementation should be exactly the same in
@@ -615,17 +615,21 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
function act(callback: () => Thenable) {
let previousActingUpdatesScopeDepth = actingUpdatesScopeDepth;
- let previousActingUpdatesSigil;
+ let previousIsSomeRendererActing;
+ let previousIsThisRendererActing;
actingUpdatesScopeDepth++;
if (__DEV__) {
- previousActingUpdatesSigil = ReactCurrentActingRendererSigil.current;
- ReactCurrentActingRendererSigil.current = ReactActingRendererSigil;
+ previousIsSomeRendererActing = IsSomeRendererActing.current;
+ previousIsThisRendererActing = IsSomeRendererActing.current;
+ IsSomeRendererActing.current = true;
+ IsThisRendererActing.current = true;
}
function onDone() {
actingUpdatesScopeDepth--;
if (__DEV__) {
- ReactCurrentActingRendererSigil.current = previousActingUpdatesSigil;
+ IsSomeRendererActing.current = previousIsSomeRendererActing;
+ IsThisRendererActing.current = previousIsThisRendererActing;
if (actingUpdatesScopeDepth > previousActingUpdatesScopeDepth) {
// if it's _less than_ previousActingUpdatesScopeDepth, then we can assume the 'other' one has warned
warningWithoutStack(
diff --git a/packages/react-reconciler/src/ReactFiberReconciler.js b/packages/react-reconciler/src/ReactFiberReconciler.js
index c97ded45a5026..be4bab8089bfe 100644
--- a/packages/react-reconciler/src/ReactFiberReconciler.js
+++ b/packages/react-reconciler/src/ReactFiberReconciler.js
@@ -57,7 +57,7 @@ import {
flushDiscreteUpdates,
flushPassiveEffects,
warnIfNotScopedWithMatchingAct,
- ReactActingRendererSigil,
+ IsThisRendererActing,
} from './ReactFiberWorkLoop';
import {createUpdate, enqueueUpdate} from './ReactUpdateQueue';
import ReactFiberInstrumentation from './ReactFiberInstrumentation';
@@ -345,7 +345,7 @@ export {
flushControlled,
flushSync,
flushPassiveEffects,
- ReactActingRendererSigil,
+ IsThisRendererActing,
};
export function getPublicRootInstance(
diff --git a/packages/react-reconciler/src/ReactFiberWorkLoop.js b/packages/react-reconciler/src/ReactFiberWorkLoop.js
index c05717bfe3eca..1c5d14651fc27 100644
--- a/packages/react-reconciler/src/ReactFiberWorkLoop.js
+++ b/packages/react-reconciler/src/ReactFiberWorkLoop.js
@@ -55,7 +55,7 @@ import {
scheduleTimeout,
cancelTimeout,
noTimeout,
- shouldWarnUnactedUpdates,
+ warnsIfNotActing,
} from './ReactFiberHostConfig';
import {createWorkInProgress, assignFiberPropertiesInDEV} from './ReactFiber';
@@ -174,7 +174,7 @@ const ceil = Math.ceil;
const {
ReactCurrentDispatcher,
ReactCurrentOwner,
- ReactCurrentActingRendererSigil,
+ IsSomeRendererActing,
} = ReactSharedInternals;
type ExecutionContext = number;
@@ -2420,18 +2420,14 @@ function warnAboutInvalidUpdatesOnClassComponentsInDEV(fiber) {
}
}
-// We export a simple object here to be used by a renderer/test-utils
-// as the value of ReactCurrentActingRendererSigil.current
-// This identity lets us identify (ha!) when the wrong renderer's act()
-// wraps anothers' updates/effects
-export const ReactActingRendererSigil = {};
+export const IsThisRendererActing = {current: (false: boolean)};
export function warnIfNotScopedWithMatchingAct(fiber: Fiber): void {
if (__DEV__) {
if (
- shouldWarnUnactedUpdates === true &&
- ReactCurrentActingRendererSigil.current !== null &&
- ReactCurrentActingRendererSigil.current !== ReactActingRendererSigil
+ warnsIfNotActing === true &&
+ IsSomeRendererActing.current === true &&
+ IsThisRendererActing.current !== true
) {
warningWithoutStack(
false,
@@ -2456,8 +2452,9 @@ export function warnIfNotScopedWithMatchingAct(fiber: Fiber): void {
export function warnIfNotCurrentlyActingEffectsInDEV(fiber: Fiber): void {
if (__DEV__) {
if (
- shouldWarnUnactedUpdates === true &&
- ReactCurrentActingRendererSigil.current !== ReactActingRendererSigil
+ warnsIfNotActing === true &&
+ IsSomeRendererActing.current === false &&
+ IsThisRendererActing.current === false
) {
warningWithoutStack(
false,
@@ -2482,9 +2479,10 @@ export function warnIfNotCurrentlyActingEffectsInDEV(fiber: Fiber): void {
function warnIfNotCurrentlyActingUpdatesInDEV(fiber: Fiber): void {
if (__DEV__) {
if (
- shouldWarnUnactedUpdates === true &&
+ warnsIfNotActing === true &&
executionContext === NoContext &&
- ReactCurrentActingRendererSigil.current !== ReactActingRendererSigil
+ IsSomeRendererActing.current === false &&
+ IsThisRendererActing.current === false
) {
warningWithoutStack(
false,
diff --git a/packages/react-reconciler/src/forks/ReactFiberHostConfig.custom.js b/packages/react-reconciler/src/forks/ReactFiberHostConfig.custom.js
index 85175c0123bfd..421ed5f625dcb 100644
--- a/packages/react-reconciler/src/forks/ReactFiberHostConfig.custom.js
+++ b/packages/react-reconciler/src/forks/ReactFiberHostConfig.custom.js
@@ -59,7 +59,7 @@ export const cancelTimeout = $$$hostConfig.clearTimeout;
export const noTimeout = $$$hostConfig.noTimeout;
export const now = $$$hostConfig.now;
export const isPrimaryRenderer = $$$hostConfig.isPrimaryRenderer;
-export const shouldWarnUnactedUpdates = $$$hostConfig.shouldWarnUnactedUpdates;
+export const warnsIfNotActing = $$$hostConfig.warnsIfNotActing;
export const supportsMutation = $$$hostConfig.supportsMutation;
export const supportsPersistence = $$$hostConfig.supportsPersistence;
export const supportsHydration = $$$hostConfig.supportsHydration;
diff --git a/packages/react-test-renderer/src/ReactTestHostConfig.js b/packages/react-test-renderer/src/ReactTestHostConfig.js
index ddd9f765cf03d..512cd0eb0ef28 100644
--- a/packages/react-test-renderer/src/ReactTestHostConfig.js
+++ b/packages/react-test-renderer/src/ReactTestHostConfig.js
@@ -217,7 +217,7 @@ export function createTextInstance(
}
export const isPrimaryRenderer = false;
-export const shouldWarnUnactedUpdates = true;
+export const warnsIfNotActing = true;
export const scheduleTimeout = setTimeout;
export const cancelTimeout = clearTimeout;
diff --git a/packages/react-test-renderer/src/ReactTestRendererAct.js b/packages/react-test-renderer/src/ReactTestRendererAct.js
index 1e47e33583a52..63aa64251b37b 100644
--- a/packages/react-test-renderer/src/ReactTestRendererAct.js
+++ b/packages/react-test-renderer/src/ReactTestRendererAct.js
@@ -11,7 +11,7 @@ import type {Thenable} from 'react-reconciler/src/ReactFiberWorkLoop';
import {
batchedUpdates,
flushPassiveEffects,
- ReactActingRendererSigil,
+ IsThisRendererActing,
} from 'react-reconciler/inline.test';
import ReactSharedInternals from 'shared/ReactSharedInternals';
import warningWithoutStack from 'shared/warningWithoutStack';
@@ -19,7 +19,7 @@ import {warnAboutMissingMockScheduler} from 'shared/ReactFeatureFlags';
import enqueueTask from 'shared/enqueueTask';
import * as Scheduler from 'scheduler';
-const {ReactCurrentActingRendererSigil} = ReactSharedInternals;
+const {IsSomeRendererActing} = ReactSharedInternals;
// this implementation should be exactly the same in
// ReactTestUtilsAct.js, ReactTestRendererAct.js, createReactNoop.js
@@ -67,17 +67,21 @@ let actingUpdatesScopeDepth = 0;
function act(callback: () => Thenable) {
let previousActingUpdatesScopeDepth = actingUpdatesScopeDepth;
- let previousActingUpdatesSigil;
+ let previousIsSomeRendererActing;
+ let previousIsThisRendererActing;
actingUpdatesScopeDepth++;
if (__DEV__) {
- previousActingUpdatesSigil = ReactCurrentActingRendererSigil.current;
- ReactCurrentActingRendererSigil.current = ReactActingRendererSigil;
+ previousIsSomeRendererActing = IsSomeRendererActing.current;
+ previousIsThisRendererActing = IsSomeRendererActing.current;
+ IsSomeRendererActing.current = true;
+ IsThisRendererActing.current = true;
}
function onDone() {
actingUpdatesScopeDepth--;
if (__DEV__) {
- ReactCurrentActingRendererSigil.current = previousActingUpdatesSigil;
+ IsSomeRendererActing.current = previousIsSomeRendererActing;
+ IsThisRendererActing.current = previousIsThisRendererActing;
if (actingUpdatesScopeDepth > previousActingUpdatesScopeDepth) {
// if it's _less than_ previousActingUpdatesScopeDepth, then we can assume the 'other' one has warned
warningWithoutStack(
diff --git a/packages/react/src/IsSomeRendererActing.js b/packages/react/src/IsSomeRendererActing.js
new file mode 100644
index 0000000000000..b2462fc6c24ce
--- /dev/null
+++ b/packages/react/src/IsSomeRendererActing.js
@@ -0,0 +1,17 @@
+/**
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ * @flow
+ */
+
+/**
+ * Used by act() to track whether you're inside an act() scope.
+ */
+
+const IsSomeRendererActing = {
+ current: (false: boolean),
+};
+export default IsSomeRendererActing;
diff --git a/packages/react/src/ReactCurrentActingRendererSigil.js b/packages/react/src/ReactCurrentActingRendererSigil.js
deleted file mode 100644
index 09e05c8362d7b..0000000000000
--- a/packages/react/src/ReactCurrentActingRendererSigil.js
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (c) Facebook, Inc. and its affiliates.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- *
- * @flow
- */
-
-/**
- * Used by act() to track whether you're outside an act() scope.
- * We use a renderer's flushPassiveEffects as the sigil value
- * so we can track identity of the renderer.
- */
-
-const ReactCurrentActingRendererSigil = {
- current: (null: null | (() => boolean)),
-};
-export default ReactCurrentActingRendererSigil;
diff --git a/packages/react/src/ReactSharedInternals.js b/packages/react/src/ReactSharedInternals.js
index 1d993139c4194..9209a86a954fc 100644
--- a/packages/react/src/ReactSharedInternals.js
+++ b/packages/react/src/ReactSharedInternals.js
@@ -10,13 +10,13 @@ import ReactCurrentDispatcher from './ReactCurrentDispatcher';
import ReactCurrentBatchConfig from './ReactCurrentBatchConfig';
import ReactCurrentOwner from './ReactCurrentOwner';
import ReactDebugCurrentFrame from './ReactDebugCurrentFrame';
-import ReactCurrentActingRendererSigil from './ReactCurrentActingRendererSigil';
+import IsSomeRendererActing from './IsSomeRendererActing';
const ReactSharedInternals = {
ReactCurrentDispatcher,
ReactCurrentBatchConfig,
ReactCurrentOwner,
- ReactCurrentActingRendererSigil,
+ IsSomeRendererActing,
// Used by renderers to avoid bundling object-assign twice in UMD bundles:
assign,
};