Skip to content

Commit 5d2fb1e

Browse files
committed
explicitly check for modes before warning, explicit tests for all modes
1 parent 4b466ce commit 5d2fb1e

File tree

2 files changed

+57
-21
lines changed

2 files changed

+57
-21
lines changed

packages/react-dom/src/__tests__/ReactTestUtilsAct-test.js

Lines changed: 53 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,59 @@ describe('ReactTestUtils.act()', () => {
6262
}
6363
}
6464
runActTests('batched mode', renderBatched, unmountBatched);
65+
66+
describe('unacted effects', () => {
67+
function App() {
68+
React.useEffect(() => {}, []);
69+
return null;
70+
}
71+
72+
it('does not warn in legacy sync mode', () => {
73+
expect(() => {
74+
ReactDOM.render(<App />, document.createElement('div'));
75+
}).toWarnDev([]);
76+
});
77+
78+
it('warns in strict mode', () => {
79+
expect(() => {
80+
ReactDOM.render(
81+
<React.StrictMode>
82+
<App />
83+
</React.StrictMode>,
84+
document.createElement('div'),
85+
);
86+
}).toWarnDev([
87+
'An update to App ran an effect, but was not wrapped in act(...)',
88+
'An update to App ran an effect, but was not wrapped in act(...)',
89+
]);
90+
});
91+
92+
it('warns in batched mode', () => {
93+
expect(() => {
94+
const root = ReactDOM.unstable_createSyncRoot(
95+
document.createElement('div'),
96+
);
97+
root.render(<App />);
98+
Scheduler.unstable_flushAll();
99+
}).toWarnDev([
100+
'An update to App ran an effect, but was not wrapped in act(...)',
101+
'An update to App ran an effect, but was not wrapped in act(...)',
102+
]);
103+
});
104+
105+
it('warns in concurrent mode', () => {
106+
expect(() => {
107+
const root = ReactDOM.unstable_createRoot(
108+
document.createElement('div'),
109+
);
110+
root.render(<App />);
111+
Scheduler.unstable_flushAll();
112+
}).toWarnDev([
113+
'An update to App ran an effect, but was not wrapped in act(...)',
114+
'An update to App ran an effect, but was not wrapped in act(...)',
115+
]);
116+
});
117+
});
65118
});
66119

67120
function runActTests(label, render, unmount) {
@@ -82,26 +135,6 @@ function runActTests(label, render, unmount) {
82135
document.body.removeChild(container);
83136
});
84137
describe('sync', () => {
85-
it('warns if an effect is queued outside an act scope, except in legacy sync+non-strict mode', () => {
86-
function App() {
87-
React.useEffect(() => {}, []);
88-
return null;
89-
}
90-
expect(() => {
91-
render(<App />, container);
92-
// flush all queued work
93-
Scheduler.unstable_flushAll();
94-
}).toWarnDev(
95-
label !== 'legacy sync mode'
96-
? [
97-
// warns twice because we're in strict+dev mode
98-
'An update to App ran an effect, but was not wrapped in act(...)',
99-
'An update to App ran an effect, but was not wrapped in act(...)',
100-
]
101-
: [],
102-
);
103-
});
104-
105138
it('can use act to flush effects', () => {
106139
function App() {
107140
React.useEffect(() => {

packages/react-reconciler/src/ReactFiberWorkLoop.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ import {
6161
import {createWorkInProgress, assignFiberPropertiesInDEV} from './ReactFiber';
6262
import {
6363
NoMode,
64+
StrictMode,
6465
ProfileMode,
6566
BatchedMode,
6667
ConcurrentMode,
@@ -2453,7 +2454,9 @@ export function warnIfNotCurrentlyActingEffectsInDEV(fiber: Fiber): void {
24532454
if (__DEV__) {
24542455
if (
24552456
warnsIfNotActing === true &&
2456-
fiber.mode &&
2457+
(fiber.mode & StrictMode ||
2458+
fiber.mode & BatchedMode ||
2459+
fiber.mode & ConcurrentMode) &&
24572460
IsSomeRendererActing.current === false &&
24582461
IsThisRendererActing.current === false
24592462
) {

0 commit comments

Comments
 (0)