diff --git a/packages/react-dom/src/__tests__/ReactTestUtilsAct-test.js b/packages/react-dom/src/__tests__/ReactTestUtilsAct-test.js index 8da49f1652451..af7ad5d89cd24 100644 --- a/packages/react-dom/src/__tests__/ReactTestUtilsAct-test.js +++ b/packages/react-dom/src/__tests__/ReactTestUtilsAct-test.js @@ -27,7 +27,7 @@ function sleep(period) { describe('ReactTestUtils.act()', () => { // first we run all the tests with concurrent mode - let concurrentRoot; + let concurrentRoot = null; function renderConcurrent(el, dom) { concurrentRoot = ReactDOM.unstable_createRoot(dom); concurrentRoot.render(el); @@ -71,7 +71,7 @@ describe('ReactTestUtils.act()', () => { runActTests('legacy sync mode', renderSync, unmountSync, rerenderSync); // and then in batched mode - let batchedRoot; + let batchedRoot = null; function renderBatched(el, dom) { batchedRoot = ReactDOM.unstable_createSyncRoot(dom); batchedRoot.render(el); @@ -791,5 +791,26 @@ function runActTests(label, render, unmount, rerender) { }); } }); + describe('warn in prod mode', () => { + it('warns if you try to use act() in prod mode', () => { + const spy = spyOnDevAndProd(console, 'error'); + + act(() => {}); + + if (!__DEV__) { + expect(console.error).toHaveBeenCalledTimes(1); + expect(console.error.calls.argsFor(0)[0]).toContain( + 'act(...) is not supported in production builds of React', + ); + } else { + expect(console.error).toHaveBeenCalledTimes(0); + } + + spy.calls.reset(); + // does not warn twice + act(() => {}); + expect(console.error).toHaveBeenCalledTimes(0); + }); + }); }); } diff --git a/packages/react-dom/src/test-utils/ReactTestUtilsAct.js b/packages/react-dom/src/test-utils/ReactTestUtilsAct.js index f12915518bdd7..52aeb03b9b2f4 100644 --- a/packages/react-dom/src/test-utils/ReactTestUtilsAct.js +++ b/packages/react-dom/src/test-utils/ReactTestUtilsAct.js @@ -74,8 +74,17 @@ function flushWorkAndMicroTasks(onDone: (err: ?Error) => void) { // so we can tell if any async act() calls try to run in parallel. let actingUpdatesScopeDepth = 0; +let didWarnAboutUsingActInProd = false; function act(callback: () => Thenable) { + if (!__DEV__) { + if (didWarnAboutUsingActInProd === false) { + didWarnAboutUsingActInProd = true; + console.error( + 'act(...) is not supported in production builds of React, and might not behave as expected.', + ); + } + } let previousActingUpdatesScopeDepth = actingUpdatesScopeDepth; let previousIsSomeRendererActing; let previousIsThisRendererActing; diff --git a/packages/react-noop-renderer/src/createReactNoop.js b/packages/react-noop-renderer/src/createReactNoop.js index 42add1285cb7c..7369552eb34e6 100644 --- a/packages/react-noop-renderer/src/createReactNoop.js +++ b/packages/react-noop-renderer/src/createReactNoop.js @@ -630,8 +630,17 @@ function createReactNoop(reconciler: Function, useMutation: boolean) { // so we can tell if any async act() calls try to run in parallel. let actingUpdatesScopeDepth = 0; + let didWarnAboutUsingActInProd = false; function act(callback: () => Thenable) { + if (!__DEV__) { + if (didWarnAboutUsingActInProd === false) { + didWarnAboutUsingActInProd = true; + console.error( + 'act(...) is not supported in production builds of React, and might not behave as expected.', + ); + } + } let previousActingUpdatesScopeDepth = actingUpdatesScopeDepth; let previousIsSomeRendererActing; let previousIsThisRendererActing; diff --git a/packages/react-test-renderer/src/ReactTestRendererAct.js b/packages/react-test-renderer/src/ReactTestRendererAct.js index 726a62a15a277..c34bd2d9f211e 100644 --- a/packages/react-test-renderer/src/ReactTestRendererAct.js +++ b/packages/react-test-renderer/src/ReactTestRendererAct.js @@ -55,8 +55,17 @@ function flushWorkAndMicroTasks(onDone: (err: ?Error) => void) { // so we can tell if any async act() calls try to run in parallel. let actingUpdatesScopeDepth = 0; +let didWarnAboutUsingActInProd = false; function act(callback: () => Thenable) { + if (!__DEV__) { + if (didWarnAboutUsingActInProd === false) { + didWarnAboutUsingActInProd = true; + console.error( + 'act(...) is not supported in production builds of React, and might not behave as expected.', + ); + } + } let previousActingUpdatesScopeDepth = actingUpdatesScopeDepth; let previousIsSomeRendererActing; let previousIsThisRendererActing; diff --git a/scripts/jest/shouldIgnoreConsoleError.js b/scripts/jest/shouldIgnoreConsoleError.js index 4ea96751c073b..cae46ac7c8c32 100644 --- a/scripts/jest/shouldIgnoreConsoleError.js +++ b/scripts/jest/shouldIgnoreConsoleError.js @@ -25,6 +25,16 @@ module.exports = function shouldIgnoreConsoleError(format, args) { // They are noisy too so we'll try to ignore them. return true; } + if ( + format.indexOf( + 'act(...) is not supported in production builds of React' + ) === 0 + ) { + // We don't yet support act() for prod builds, and warn for it. + // But we'd like to use act() ourselves for prod builds. + // Let's ignore the warning and #yolo. + return true; + } } // Looks legit return false;