From fdec8c12dd9a4c38453a30a8f33407caaf619312 Mon Sep 17 00:00:00 2001 From: Rena Wolford Date: Tue, 2 Jul 2019 22:20:17 +0100 Subject: [PATCH] allow nested `act()`s from different renderers (#16039) * allow nested `act()`s from different renderers There are usecases where multiple renderers need to oprate inside an act() scope - ReactDOM.render being used inside another component tree. The parent component will be rendered using ReactTestRenderer.create for a snapshot test or something. - a ReactDOM instance interacting with a ReactTestRenderer instance (like for the new devtools) This PR changes the way the acting sigils operate to allow for this. It keeps 2 booleans, one attached to React, one attached to the renderer. act() changes these values, and the workloop reads them to decide what warning to trigger. I also renamed shouldWarnUnactedUpdates to warnsIfNotActing * s/ReactIsActing/IsSomeRendererActing and s/ReactRendererIsActing/IsThisRendererActing --- src/ReactTestHostConfig.js | 2 +- src/ReactTestRendererAct.js | 16 ++++++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/ReactTestHostConfig.js b/src/ReactTestHostConfig.js index ddd9f76..512cd0e 100644 --- a/src/ReactTestHostConfig.js +++ b/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/src/ReactTestRendererAct.js b/src/ReactTestRendererAct.js index 1e47e33..63aa642 100644 --- a/src/ReactTestRendererAct.js +++ b/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(