mirror of
https://github.com/hanzoai/react.git
synced 2026-09-24 17:02:27 +00:00
Stop using Scheduler.log to test double invocations (#29008)
This commit is contained in:
committed by
GitHub
parent
7fff0270fb
commit
4d232a05fd
@@ -161,7 +161,11 @@ describe('ReactInternalTestUtils', () => {
|
||||
|
||||
const root = ReactNoop.createRoot();
|
||||
await act(() => {
|
||||
root.render(<App />);
|
||||
root.render(
|
||||
<React.StrictMode>
|
||||
<App />
|
||||
</React.StrictMode>
|
||||
);
|
||||
});
|
||||
assertLog(['A', 'B', 'C']);
|
||||
});
|
||||
|
||||
+156
-136
@@ -11,33 +11,29 @@
|
||||
|
||||
let React;
|
||||
let ReactNoop;
|
||||
let Scheduler;
|
||||
let act;
|
||||
let assertLog;
|
||||
|
||||
describe('StrictEffectsMode', () => {
|
||||
beforeEach(() => {
|
||||
jest.resetModules();
|
||||
act = require('internal-test-utils').act;
|
||||
const InternalTestUtils = require('internal-test-utils');
|
||||
assertLog = InternalTestUtils.assertLog;
|
||||
|
||||
React = require('react');
|
||||
Scheduler = require('scheduler');
|
||||
ReactNoop = require('react-noop-renderer');
|
||||
});
|
||||
|
||||
// @gate !disableLegacyMode
|
||||
it('should not double invoke effects in legacy mode', async () => {
|
||||
const log = [];
|
||||
function App({text}) {
|
||||
React.useEffect(() => {
|
||||
Scheduler.log('useEffect mount');
|
||||
return () => Scheduler.log('useEffect unmount');
|
||||
log.push('useEffect mount');
|
||||
return () => log.push('useEffect unmount');
|
||||
});
|
||||
|
||||
React.useLayoutEffect(() => {
|
||||
Scheduler.log('useLayoutEffect mount');
|
||||
return () => Scheduler.log('useLayoutEffect unmount');
|
||||
log.push('useLayoutEffect mount');
|
||||
return () => log.push('useLayoutEffect unmount');
|
||||
});
|
||||
|
||||
return text;
|
||||
@@ -52,19 +48,20 @@ describe('StrictEffectsMode', () => {
|
||||
);
|
||||
});
|
||||
|
||||
assertLog(['useLayoutEffect mount', 'useEffect mount']);
|
||||
expect(log).toEqual(['useLayoutEffect mount', 'useEffect mount']);
|
||||
});
|
||||
|
||||
it('double invoking for effects works properly', async () => {
|
||||
const log = [];
|
||||
function App({text}) {
|
||||
React.useEffect(() => {
|
||||
Scheduler.log('useEffect mount');
|
||||
return () => Scheduler.log('useEffect unmount');
|
||||
log.push('useEffect mount');
|
||||
return () => log.push('useEffect unmount');
|
||||
});
|
||||
|
||||
React.useLayoutEffect(() => {
|
||||
Scheduler.log('useLayoutEffect mount');
|
||||
return () => Scheduler.log('useLayoutEffect unmount');
|
||||
log.push('useLayoutEffect mount');
|
||||
return () => log.push('useLayoutEffect unmount');
|
||||
});
|
||||
|
||||
return text;
|
||||
@@ -80,7 +77,7 @@ describe('StrictEffectsMode', () => {
|
||||
});
|
||||
|
||||
if (__DEV__) {
|
||||
assertLog([
|
||||
expect(log).toEqual([
|
||||
'useLayoutEffect mount',
|
||||
'useEffect mount',
|
||||
'useLayoutEffect unmount',
|
||||
@@ -89,9 +86,10 @@ describe('StrictEffectsMode', () => {
|
||||
'useEffect mount',
|
||||
]);
|
||||
} else {
|
||||
assertLog(['useLayoutEffect mount', 'useEffect mount']);
|
||||
expect(log).toEqual(['useLayoutEffect mount', 'useEffect mount']);
|
||||
}
|
||||
|
||||
log.length = 0;
|
||||
await act(() => {
|
||||
ReactNoop.renderToRootWithID(
|
||||
<React.StrictMode>
|
||||
@@ -101,30 +99,32 @@ describe('StrictEffectsMode', () => {
|
||||
);
|
||||
});
|
||||
|
||||
assertLog([
|
||||
expect(log).toEqual([
|
||||
'useLayoutEffect unmount',
|
||||
'useLayoutEffect mount',
|
||||
'useEffect unmount',
|
||||
'useEffect mount',
|
||||
]);
|
||||
|
||||
log.length = 0;
|
||||
await act(() => {
|
||||
ReactNoop.unmountRootWithID('root');
|
||||
});
|
||||
|
||||
assertLog(['useLayoutEffect unmount', 'useEffect unmount']);
|
||||
expect(log).toEqual(['useLayoutEffect unmount', 'useEffect unmount']);
|
||||
});
|
||||
|
||||
it('multiple effects are double invoked in the right order (all mounted, all unmounted, all remounted)', async () => {
|
||||
const log = [];
|
||||
function App({text}) {
|
||||
React.useEffect(() => {
|
||||
Scheduler.log('useEffect One mount');
|
||||
return () => Scheduler.log('useEffect One unmount');
|
||||
log.push('useEffect One mount');
|
||||
return () => log.push('useEffect One unmount');
|
||||
});
|
||||
|
||||
React.useEffect(() => {
|
||||
Scheduler.log('useEffect Two mount');
|
||||
return () => Scheduler.log('useEffect Two unmount');
|
||||
log.push('useEffect Two mount');
|
||||
return () => log.push('useEffect Two unmount');
|
||||
});
|
||||
|
||||
return text;
|
||||
@@ -140,7 +140,7 @@ describe('StrictEffectsMode', () => {
|
||||
});
|
||||
|
||||
if (__DEV__) {
|
||||
assertLog([
|
||||
expect(log).toEqual([
|
||||
'useEffect One mount',
|
||||
'useEffect Two mount',
|
||||
'useEffect One unmount',
|
||||
@@ -149,9 +149,10 @@ describe('StrictEffectsMode', () => {
|
||||
'useEffect Two mount',
|
||||
]);
|
||||
} else {
|
||||
assertLog(['useEffect One mount', 'useEffect Two mount']);
|
||||
expect(log).toEqual(['useEffect One mount', 'useEffect Two mount']);
|
||||
}
|
||||
|
||||
log.length = 0;
|
||||
await act(() => {
|
||||
ReactNoop.renderToRootWithID(
|
||||
<React.StrictMode>
|
||||
@@ -161,30 +162,32 @@ describe('StrictEffectsMode', () => {
|
||||
);
|
||||
});
|
||||
|
||||
assertLog([
|
||||
expect(log).toEqual([
|
||||
'useEffect One unmount',
|
||||
'useEffect Two unmount',
|
||||
'useEffect One mount',
|
||||
'useEffect Two mount',
|
||||
]);
|
||||
|
||||
log.length = 0;
|
||||
await act(() => {
|
||||
ReactNoop.unmountRootWithID('root');
|
||||
});
|
||||
|
||||
assertLog(['useEffect One unmount', 'useEffect Two unmount']);
|
||||
expect(log).toEqual(['useEffect One unmount', 'useEffect Two unmount']);
|
||||
});
|
||||
|
||||
it('multiple layout effects are double invoked in the right order (all mounted, all unmounted, all remounted)', async () => {
|
||||
const log = [];
|
||||
function App({text}) {
|
||||
React.useLayoutEffect(() => {
|
||||
Scheduler.log('useLayoutEffect One mount');
|
||||
return () => Scheduler.log('useLayoutEffect One unmount');
|
||||
log.push('useLayoutEffect One mount');
|
||||
return () => log.push('useLayoutEffect One unmount');
|
||||
});
|
||||
|
||||
React.useLayoutEffect(() => {
|
||||
Scheduler.log('useLayoutEffect Two mount');
|
||||
return () => Scheduler.log('useLayoutEffect Two unmount');
|
||||
log.push('useLayoutEffect Two mount');
|
||||
return () => log.push('useLayoutEffect Two unmount');
|
||||
});
|
||||
|
||||
return text;
|
||||
@@ -200,7 +203,7 @@ describe('StrictEffectsMode', () => {
|
||||
});
|
||||
|
||||
if (__DEV__) {
|
||||
assertLog([
|
||||
expect(log).toEqual([
|
||||
'useLayoutEffect One mount',
|
||||
'useLayoutEffect Two mount',
|
||||
'useLayoutEffect One unmount',
|
||||
@@ -209,9 +212,13 @@ describe('StrictEffectsMode', () => {
|
||||
'useLayoutEffect Two mount',
|
||||
]);
|
||||
} else {
|
||||
assertLog(['useLayoutEffect One mount', 'useLayoutEffect Two mount']);
|
||||
expect(log).toEqual([
|
||||
'useLayoutEffect One mount',
|
||||
'useLayoutEffect Two mount',
|
||||
]);
|
||||
}
|
||||
|
||||
log.length = 0;
|
||||
await act(() => {
|
||||
ReactNoop.renderToRootWithID(
|
||||
<React.StrictMode>
|
||||
@@ -221,28 +228,33 @@ describe('StrictEffectsMode', () => {
|
||||
);
|
||||
});
|
||||
|
||||
assertLog([
|
||||
expect(log).toEqual([
|
||||
'useLayoutEffect One unmount',
|
||||
'useLayoutEffect Two unmount',
|
||||
'useLayoutEffect One mount',
|
||||
'useLayoutEffect Two mount',
|
||||
]);
|
||||
|
||||
log.length = 0;
|
||||
await act(() => {
|
||||
ReactNoop.unmountRootWithID('root');
|
||||
});
|
||||
|
||||
assertLog(['useLayoutEffect One unmount', 'useLayoutEffect Two unmount']);
|
||||
expect(log).toEqual([
|
||||
'useLayoutEffect One unmount',
|
||||
'useLayoutEffect Two unmount',
|
||||
]);
|
||||
});
|
||||
|
||||
it('useEffect and useLayoutEffect is called twice when there is no unmount', async () => {
|
||||
const log = [];
|
||||
function App({text}) {
|
||||
React.useEffect(() => {
|
||||
Scheduler.log('useEffect mount');
|
||||
log.push('useEffect mount');
|
||||
});
|
||||
|
||||
React.useLayoutEffect(() => {
|
||||
Scheduler.log('useLayoutEffect mount');
|
||||
log.push('useLayoutEffect mount');
|
||||
});
|
||||
|
||||
return text;
|
||||
@@ -257,16 +269,17 @@ describe('StrictEffectsMode', () => {
|
||||
});
|
||||
|
||||
if (__DEV__) {
|
||||
assertLog([
|
||||
expect(log).toEqual([
|
||||
'useLayoutEffect mount',
|
||||
'useEffect mount',
|
||||
'useLayoutEffect mount',
|
||||
'useEffect mount',
|
||||
]);
|
||||
} else {
|
||||
assertLog(['useLayoutEffect mount', 'useEffect mount']);
|
||||
expect(log).toEqual(['useLayoutEffect mount', 'useEffect mount']);
|
||||
}
|
||||
|
||||
log.length = 0;
|
||||
await act(() => {
|
||||
ReactNoop.renderToRootWithID(
|
||||
<React.StrictMode>
|
||||
@@ -275,32 +288,34 @@ describe('StrictEffectsMode', () => {
|
||||
);
|
||||
});
|
||||
|
||||
assertLog(['useLayoutEffect mount', 'useEffect mount']);
|
||||
expect(log).toEqual(['useLayoutEffect mount', 'useEffect mount']);
|
||||
|
||||
log.length = 0;
|
||||
await act(() => {
|
||||
ReactNoop.unmountRootWithID('root');
|
||||
});
|
||||
|
||||
assertLog([]);
|
||||
expect(log).toEqual([]);
|
||||
});
|
||||
|
||||
it('passes the right context to class component lifecycles', async () => {
|
||||
const log = [];
|
||||
class App extends React.PureComponent {
|
||||
test() {}
|
||||
|
||||
componentDidMount() {
|
||||
this.test();
|
||||
Scheduler.log('componentDidMount');
|
||||
log.push('componentDidMount');
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
this.test();
|
||||
Scheduler.log('componentDidUpdate');
|
||||
log.push('componentDidUpdate');
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.test();
|
||||
Scheduler.log('componentWillUnmount');
|
||||
log.push('componentWillUnmount');
|
||||
}
|
||||
|
||||
render() {
|
||||
@@ -317,28 +332,29 @@ describe('StrictEffectsMode', () => {
|
||||
});
|
||||
|
||||
if (__DEV__) {
|
||||
assertLog([
|
||||
expect(log).toEqual([
|
||||
'componentDidMount',
|
||||
'componentWillUnmount',
|
||||
'componentDidMount',
|
||||
]);
|
||||
} else {
|
||||
assertLog(['componentDidMount']);
|
||||
expect(log).toEqual(['componentDidMount']);
|
||||
}
|
||||
});
|
||||
|
||||
it('double invoking works for class components', async () => {
|
||||
const log = [];
|
||||
class App extends React.PureComponent {
|
||||
componentDidMount() {
|
||||
Scheduler.log('componentDidMount');
|
||||
log.push('componentDidMount');
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
Scheduler.log('componentDidUpdate');
|
||||
log.push('componentDidUpdate');
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
Scheduler.log('componentWillUnmount');
|
||||
log.push('componentWillUnmount');
|
||||
}
|
||||
|
||||
render() {
|
||||
@@ -356,15 +372,16 @@ describe('StrictEffectsMode', () => {
|
||||
});
|
||||
|
||||
if (__DEV__) {
|
||||
assertLog([
|
||||
expect(log).toEqual([
|
||||
'componentDidMount',
|
||||
'componentWillUnmount',
|
||||
'componentDidMount',
|
||||
]);
|
||||
} else {
|
||||
assertLog(['componentDidMount']);
|
||||
expect(log).toEqual(['componentDidMount']);
|
||||
}
|
||||
|
||||
log.length = 0;
|
||||
await act(() => {
|
||||
ReactNoop.renderToRootWithID(
|
||||
<React.StrictMode>
|
||||
@@ -374,23 +391,25 @@ describe('StrictEffectsMode', () => {
|
||||
);
|
||||
});
|
||||
|
||||
assertLog(['componentDidUpdate']);
|
||||
expect(log).toEqual(['componentDidUpdate']);
|
||||
|
||||
log.length = 0;
|
||||
await act(() => {
|
||||
ReactNoop.unmountRootWithID('root');
|
||||
});
|
||||
|
||||
assertLog(['componentWillUnmount']);
|
||||
expect(log).toEqual(['componentWillUnmount']);
|
||||
});
|
||||
|
||||
it('invokes componentWillUnmount for class components without componentDidMount', async () => {
|
||||
const log = [];
|
||||
class App extends React.PureComponent {
|
||||
componentDidUpdate() {
|
||||
Scheduler.log('componentDidUpdate');
|
||||
log.push('componentDidUpdate');
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
Scheduler.log('componentWillUnmount');
|
||||
log.push('componentWillUnmount');
|
||||
}
|
||||
|
||||
render() {
|
||||
@@ -408,11 +427,12 @@ describe('StrictEffectsMode', () => {
|
||||
});
|
||||
|
||||
if (__DEV__) {
|
||||
assertLog(['componentWillUnmount']);
|
||||
expect(log).toEqual(['componentWillUnmount']);
|
||||
} else {
|
||||
assertLog([]);
|
||||
expect(log).toEqual([]);
|
||||
}
|
||||
|
||||
log.length = 0;
|
||||
await act(() => {
|
||||
ReactNoop.renderToRootWithID(
|
||||
<React.StrictMode>
|
||||
@@ -422,28 +442,30 @@ describe('StrictEffectsMode', () => {
|
||||
);
|
||||
});
|
||||
|
||||
assertLog(['componentDidUpdate']);
|
||||
expect(log).toEqual(['componentDidUpdate']);
|
||||
|
||||
log.length = 0;
|
||||
await act(() => {
|
||||
ReactNoop.unmountRootWithID('root');
|
||||
});
|
||||
|
||||
assertLog(['componentWillUnmount']);
|
||||
expect(log).toEqual(['componentWillUnmount']);
|
||||
});
|
||||
|
||||
// @gate !disableLegacyMode
|
||||
it('should not double invoke class lifecycles in legacy mode', async () => {
|
||||
const log = [];
|
||||
class App extends React.PureComponent {
|
||||
componentDidMount() {
|
||||
Scheduler.log('componentDidMount');
|
||||
log.push('componentDidMount');
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
Scheduler.log('componentDidUpdate');
|
||||
log.push('componentDidUpdate');
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
Scheduler.log('componentWillUnmount');
|
||||
log.push('componentWillUnmount');
|
||||
}
|
||||
|
||||
render() {
|
||||
@@ -460,26 +482,27 @@ describe('StrictEffectsMode', () => {
|
||||
);
|
||||
});
|
||||
|
||||
assertLog(['componentDidMount']);
|
||||
expect(log).toEqual(['componentDidMount']);
|
||||
});
|
||||
|
||||
it('double flushing passive effects only results in one double invoke', async () => {
|
||||
const log = [];
|
||||
function App({text}) {
|
||||
const [state, setState] = React.useState(0);
|
||||
React.useEffect(() => {
|
||||
if (state !== 1) {
|
||||
setState(1);
|
||||
}
|
||||
Scheduler.log('useEffect mount');
|
||||
return () => Scheduler.log('useEffect unmount');
|
||||
log.push('useEffect mount');
|
||||
return () => log.push('useEffect unmount');
|
||||
});
|
||||
|
||||
React.useLayoutEffect(() => {
|
||||
Scheduler.log('useLayoutEffect mount');
|
||||
return () => Scheduler.log('useLayoutEffect unmount');
|
||||
log.push('useLayoutEffect mount');
|
||||
return () => log.push('useLayoutEffect unmount');
|
||||
});
|
||||
|
||||
Scheduler.log(text);
|
||||
log.push(text);
|
||||
return text;
|
||||
}
|
||||
|
||||
@@ -492,7 +515,8 @@ describe('StrictEffectsMode', () => {
|
||||
});
|
||||
|
||||
if (__DEV__) {
|
||||
assertLog([
|
||||
expect(log).toEqual([
|
||||
'mount',
|
||||
'mount',
|
||||
'useLayoutEffect mount',
|
||||
'useEffect mount',
|
||||
@@ -501,13 +525,14 @@ describe('StrictEffectsMode', () => {
|
||||
'useLayoutEffect mount',
|
||||
'useEffect mount',
|
||||
'mount',
|
||||
'mount',
|
||||
'useLayoutEffect unmount',
|
||||
'useLayoutEffect mount',
|
||||
'useEffect unmount',
|
||||
'useEffect mount',
|
||||
]);
|
||||
} else {
|
||||
assertLog([
|
||||
expect(log).toEqual([
|
||||
'mount',
|
||||
'useLayoutEffect mount',
|
||||
'useEffect mount',
|
||||
@@ -521,15 +546,16 @@ describe('StrictEffectsMode', () => {
|
||||
});
|
||||
|
||||
it('newly mounted components after initial mount get double invoked', async () => {
|
||||
const log = [];
|
||||
let _setShowChild;
|
||||
function Child() {
|
||||
React.useEffect(() => {
|
||||
Scheduler.log('Child useEffect mount');
|
||||
return () => Scheduler.log('Child useEffect unmount');
|
||||
log.push('Child useEffect mount');
|
||||
return () => log.push('Child useEffect unmount');
|
||||
});
|
||||
React.useLayoutEffect(() => {
|
||||
Scheduler.log('Child useLayoutEffect mount');
|
||||
return () => Scheduler.log('Child useLayoutEffect unmount');
|
||||
log.push('Child useLayoutEffect mount');
|
||||
return () => log.push('Child useLayoutEffect unmount');
|
||||
});
|
||||
|
||||
return null;
|
||||
@@ -539,12 +565,12 @@ describe('StrictEffectsMode', () => {
|
||||
const [showChild, setShowChild] = React.useState(false);
|
||||
_setShowChild = setShowChild;
|
||||
React.useEffect(() => {
|
||||
Scheduler.log('App useEffect mount');
|
||||
return () => Scheduler.log('App useEffect unmount');
|
||||
log.push('App useEffect mount');
|
||||
return () => log.push('App useEffect unmount');
|
||||
});
|
||||
React.useLayoutEffect(() => {
|
||||
Scheduler.log('App useLayoutEffect mount');
|
||||
return () => Scheduler.log('App useLayoutEffect unmount');
|
||||
log.push('App useLayoutEffect mount');
|
||||
return () => log.push('App useLayoutEffect unmount');
|
||||
});
|
||||
|
||||
return showChild && <Child />;
|
||||
@@ -560,7 +586,7 @@ describe('StrictEffectsMode', () => {
|
||||
});
|
||||
|
||||
if (__DEV__) {
|
||||
assertLog([
|
||||
expect(log).toEqual([
|
||||
'App useLayoutEffect mount',
|
||||
'App useEffect mount',
|
||||
'App useLayoutEffect unmount',
|
||||
@@ -569,15 +595,16 @@ describe('StrictEffectsMode', () => {
|
||||
'App useEffect mount',
|
||||
]);
|
||||
} else {
|
||||
assertLog(['App useLayoutEffect mount', 'App useEffect mount']);
|
||||
expect(log).toEqual(['App useLayoutEffect mount', 'App useEffect mount']);
|
||||
}
|
||||
|
||||
log.length = 0;
|
||||
await act(() => {
|
||||
_setShowChild(true);
|
||||
});
|
||||
|
||||
if (__DEV__) {
|
||||
assertLog([
|
||||
expect(log).toEqual([
|
||||
'App useLayoutEffect unmount',
|
||||
'Child useLayoutEffect mount',
|
||||
'App useLayoutEffect mount',
|
||||
@@ -590,7 +617,7 @@ describe('StrictEffectsMode', () => {
|
||||
'Child useEffect mount',
|
||||
]);
|
||||
} else {
|
||||
assertLog([
|
||||
expect(log).toEqual([
|
||||
'App useLayoutEffect unmount',
|
||||
'Child useLayoutEffect mount',
|
||||
'App useLayoutEffect mount',
|
||||
@@ -602,13 +629,14 @@ describe('StrictEffectsMode', () => {
|
||||
});
|
||||
|
||||
it('classes and functions are double invoked together correctly', async () => {
|
||||
const log = [];
|
||||
class ClassChild extends React.PureComponent {
|
||||
componentDidMount() {
|
||||
Scheduler.log('componentDidMount');
|
||||
log.push('componentDidMount');
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
Scheduler.log('componentWillUnmount');
|
||||
log.push('componentWillUnmount');
|
||||
}
|
||||
|
||||
render() {
|
||||
@@ -618,12 +646,12 @@ describe('StrictEffectsMode', () => {
|
||||
|
||||
function FunctionChild({text}) {
|
||||
React.useEffect(() => {
|
||||
Scheduler.log('useEffect mount');
|
||||
return () => Scheduler.log('useEffect unmount');
|
||||
log.push('useEffect mount');
|
||||
return () => log.push('useEffect unmount');
|
||||
});
|
||||
React.useLayoutEffect(() => {
|
||||
Scheduler.log('useLayoutEffect mount');
|
||||
return () => Scheduler.log('useLayoutEffect unmount');
|
||||
log.push('useLayoutEffect mount');
|
||||
return () => log.push('useLayoutEffect unmount');
|
||||
});
|
||||
return text;
|
||||
}
|
||||
@@ -647,7 +675,7 @@ describe('StrictEffectsMode', () => {
|
||||
});
|
||||
|
||||
if (__DEV__) {
|
||||
assertLog([
|
||||
expect(log).toEqual([
|
||||
'componentDidMount',
|
||||
'useLayoutEffect mount',
|
||||
'useEffect mount',
|
||||
@@ -659,13 +687,14 @@ describe('StrictEffectsMode', () => {
|
||||
'useEffect mount',
|
||||
]);
|
||||
} else {
|
||||
assertLog([
|
||||
expect(log).toEqual([
|
||||
'componentDidMount',
|
||||
'useLayoutEffect mount',
|
||||
'useEffect mount',
|
||||
]);
|
||||
}
|
||||
|
||||
log.length = 0;
|
||||
await act(() => {
|
||||
ReactNoop.renderToRootWithID(
|
||||
<React.StrictMode>
|
||||
@@ -675,18 +704,19 @@ describe('StrictEffectsMode', () => {
|
||||
);
|
||||
});
|
||||
|
||||
assertLog([
|
||||
expect(log).toEqual([
|
||||
'useLayoutEffect unmount',
|
||||
'useLayoutEffect mount',
|
||||
'useEffect unmount',
|
||||
'useEffect mount',
|
||||
]);
|
||||
|
||||
log.length = 0;
|
||||
await act(() => {
|
||||
ReactNoop.unmountRootWithID('root');
|
||||
});
|
||||
|
||||
assertLog([
|
||||
expect(log).toEqual([
|
||||
'componentWillUnmount',
|
||||
'useLayoutEffect unmount',
|
||||
'useEffect unmount',
|
||||
@@ -694,9 +724,10 @@ describe('StrictEffectsMode', () => {
|
||||
});
|
||||
|
||||
it('classes without componentDidMount and functions are double invoked together correctly', async () => {
|
||||
const log = [];
|
||||
class ClassChild extends React.PureComponent {
|
||||
componentWillUnmount() {
|
||||
Scheduler.log('componentWillUnmount');
|
||||
log.push('componentWillUnmount');
|
||||
}
|
||||
|
||||
render() {
|
||||
@@ -706,12 +737,12 @@ describe('StrictEffectsMode', () => {
|
||||
|
||||
function FunctionChild({text}) {
|
||||
React.useEffect(() => {
|
||||
Scheduler.log('useEffect mount');
|
||||
return () => Scheduler.log('useEffect unmount');
|
||||
log.push('useEffect mount');
|
||||
return () => log.push('useEffect unmount');
|
||||
});
|
||||
React.useLayoutEffect(() => {
|
||||
Scheduler.log('useLayoutEffect mount');
|
||||
return () => Scheduler.log('useLayoutEffect unmount');
|
||||
log.push('useLayoutEffect mount');
|
||||
return () => log.push('useLayoutEffect unmount');
|
||||
});
|
||||
return text;
|
||||
}
|
||||
@@ -735,7 +766,7 @@ describe('StrictEffectsMode', () => {
|
||||
});
|
||||
|
||||
if (__DEV__) {
|
||||
assertLog([
|
||||
expect(log).toEqual([
|
||||
'useLayoutEffect mount',
|
||||
'useEffect mount',
|
||||
'componentWillUnmount',
|
||||
@@ -745,9 +776,10 @@ describe('StrictEffectsMode', () => {
|
||||
'useEffect mount',
|
||||
]);
|
||||
} else {
|
||||
assertLog(['useLayoutEffect mount', 'useEffect mount']);
|
||||
expect(log).toEqual(['useLayoutEffect mount', 'useEffect mount']);
|
||||
}
|
||||
|
||||
log.length = 0;
|
||||
await act(() => {
|
||||
ReactNoop.renderToRootWithID(
|
||||
<React.StrictMode>
|
||||
@@ -757,18 +789,19 @@ describe('StrictEffectsMode', () => {
|
||||
);
|
||||
});
|
||||
|
||||
assertLog([
|
||||
expect(log).toEqual([
|
||||
'useLayoutEffect unmount',
|
||||
'useLayoutEffect mount',
|
||||
'useEffect unmount',
|
||||
'useEffect mount',
|
||||
]);
|
||||
|
||||
log.length = 0;
|
||||
await act(() => {
|
||||
ReactNoop.unmountRootWithID('root');
|
||||
});
|
||||
|
||||
assertLog([
|
||||
expect(log).toEqual([
|
||||
'componentWillUnmount',
|
||||
'useLayoutEffect unmount',
|
||||
'useEffect unmount',
|
||||
@@ -777,7 +810,7 @@ describe('StrictEffectsMode', () => {
|
||||
|
||||
// @gate __DEV__
|
||||
it('should double invoke effects after a re-suspend', async () => {
|
||||
// Not using Scheduler.log because it silences double render logs.
|
||||
// Not using log.push because it silences double render logs.
|
||||
let log = [];
|
||||
let shouldSuspend = true;
|
||||
let resolve;
|
||||
@@ -867,8 +900,17 @@ describe('StrictEffectsMode', () => {
|
||||
);
|
||||
});
|
||||
|
||||
expect(log).toEqual([
|
||||
'Parent rendered',
|
||||
'Parent rendered',
|
||||
'Child rendered',
|
||||
'Child suspended',
|
||||
'Fallback',
|
||||
'Fallback',
|
||||
]);
|
||||
|
||||
log = [];
|
||||
// while suspended, update
|
||||
log.push('-----------------------after update');
|
||||
await act(() => {
|
||||
ReactNoop.render(
|
||||
<React.StrictMode>
|
||||
@@ -877,9 +919,19 @@ describe('StrictEffectsMode', () => {
|
||||
);
|
||||
});
|
||||
|
||||
// Now resolve and commit
|
||||
log.push('-----------------------after suspense');
|
||||
expect(log).toEqual([
|
||||
'Parent rendered',
|
||||
'Parent rendered',
|
||||
'Child rendered',
|
||||
'Child suspended',
|
||||
'Fallback',
|
||||
'Fallback',
|
||||
'Parent dep destroy',
|
||||
'Parent dep create',
|
||||
]);
|
||||
|
||||
log = [];
|
||||
// Now resolve and commit
|
||||
await act(() => {
|
||||
resolve();
|
||||
shouldSuspend = false;
|
||||
@@ -887,22 +939,6 @@ describe('StrictEffectsMode', () => {
|
||||
|
||||
if (gate(flags => flags.useModernStrictMode)) {
|
||||
expect(log).toEqual([
|
||||
'Parent rendered',
|
||||
'Parent rendered',
|
||||
'Child rendered',
|
||||
'Child suspended',
|
||||
'Fallback',
|
||||
'Fallback',
|
||||
'-----------------------after update',
|
||||
'Parent rendered',
|
||||
'Parent rendered',
|
||||
'Child rendered',
|
||||
'Child suspended',
|
||||
'Fallback',
|
||||
'Fallback',
|
||||
'Parent dep destroy',
|
||||
'Parent dep create',
|
||||
'-----------------------after suspense',
|
||||
'Child rendered',
|
||||
'Child rendered',
|
||||
// !!! Committed, destroy and create effect.
|
||||
@@ -924,22 +960,6 @@ describe('StrictEffectsMode', () => {
|
||||
]);
|
||||
} else {
|
||||
expect(log).toEqual([
|
||||
'Parent rendered',
|
||||
'Parent rendered',
|
||||
'Child rendered',
|
||||
'Child suspended',
|
||||
'Fallback',
|
||||
'Fallback',
|
||||
'-----------------------after update',
|
||||
'Parent rendered',
|
||||
'Parent rendered',
|
||||
'Child rendered',
|
||||
'Child suspended',
|
||||
'Fallback',
|
||||
'Fallback',
|
||||
'Parent dep destroy',
|
||||
'Parent dep create',
|
||||
'-----------------------after suspense',
|
||||
'Child rendered',
|
||||
'Child rendered',
|
||||
'Child dep destroy',
|
||||
|
||||
+161
-76
@@ -13,7 +13,6 @@ let React;
|
||||
let ReactNoop;
|
||||
let Scheduler;
|
||||
let act;
|
||||
let assertLog;
|
||||
let waitFor;
|
||||
let waitForAll;
|
||||
let waitForPaint;
|
||||
@@ -31,20 +30,20 @@ describe('StrictEffectsMode defaults', () => {
|
||||
waitFor = InternalTestUtils.waitFor;
|
||||
waitForAll = InternalTestUtils.waitForAll;
|
||||
waitForPaint = InternalTestUtils.waitForPaint;
|
||||
assertLog = InternalTestUtils.assertLog;
|
||||
});
|
||||
|
||||
// @gate !disableLegacyMode
|
||||
it('should not double invoke effects in legacy mode', async () => {
|
||||
const log = [];
|
||||
function App({text}) {
|
||||
React.useEffect(() => {
|
||||
Scheduler.log('useEffect mount');
|
||||
return () => Scheduler.log('useEffect unmount');
|
||||
log.push('useEffect mount');
|
||||
return () => log.push('useEffect unmount');
|
||||
});
|
||||
|
||||
React.useLayoutEffect(() => {
|
||||
Scheduler.log('useLayoutEffect mount');
|
||||
return () => Scheduler.log('useLayoutEffect unmount');
|
||||
log.push('useLayoutEffect mount');
|
||||
return () => log.push('useLayoutEffect unmount');
|
||||
});
|
||||
|
||||
return text;
|
||||
@@ -58,22 +57,23 @@ describe('StrictEffectsMode defaults', () => {
|
||||
);
|
||||
});
|
||||
|
||||
assertLog(['useLayoutEffect mount', 'useEffect mount']);
|
||||
expect(log).toEqual(['useLayoutEffect mount', 'useEffect mount']);
|
||||
});
|
||||
|
||||
// @gate !disableLegacyMode
|
||||
it('should not double invoke class lifecycles in legacy mode', async () => {
|
||||
const log = [];
|
||||
class App extends React.PureComponent {
|
||||
componentDidMount() {
|
||||
Scheduler.log('componentDidMount');
|
||||
log.push('componentDidMount');
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
Scheduler.log('componentDidUpdate');
|
||||
log.push('componentDidUpdate');
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
Scheduler.log('componentWillUnmount');
|
||||
log.push('componentWillUnmount');
|
||||
}
|
||||
|
||||
render() {
|
||||
@@ -89,15 +89,20 @@ describe('StrictEffectsMode defaults', () => {
|
||||
);
|
||||
});
|
||||
|
||||
assertLog(['componentDidMount']);
|
||||
expect(log).toEqual(['componentDidMount']);
|
||||
});
|
||||
|
||||
if (__DEV__) {
|
||||
it('should flush double-invoked effects within the same frame as layout effects if there are no passive effects', async () => {
|
||||
const log = [];
|
||||
function ComponentWithEffects({label}) {
|
||||
React.useLayoutEffect(() => {
|
||||
Scheduler.log(`useLayoutEffect mount "${label}"`);
|
||||
return () => Scheduler.log(`useLayoutEffect unmount "${label}"`);
|
||||
log.push(`useLayoutEffect mount "${label}"`);
|
||||
return () => {
|
||||
Scheduler.log(`useLayoutEffect unmount "${label}"`);
|
||||
log.push(`useLayoutEffect unmount "${label}"`);
|
||||
};
|
||||
});
|
||||
|
||||
return label;
|
||||
@@ -115,8 +120,14 @@ describe('StrictEffectsMode defaults', () => {
|
||||
'useLayoutEffect unmount "one"',
|
||||
'useLayoutEffect mount "one"',
|
||||
]);
|
||||
expect(log).toEqual([
|
||||
'useLayoutEffect mount "one"',
|
||||
'useLayoutEffect unmount "one"',
|
||||
'useLayoutEffect mount "one"',
|
||||
]);
|
||||
});
|
||||
|
||||
log.length = 0;
|
||||
await act(async () => {
|
||||
ReactNoop.render(
|
||||
<React.StrictMode>
|
||||
@@ -125,13 +136,23 @@ describe('StrictEffectsMode defaults', () => {
|
||||
</React.StrictMode>,
|
||||
);
|
||||
|
||||
assertLog([]);
|
||||
expect(log).toEqual([]);
|
||||
await waitForPaint([
|
||||
// Cleanup and re-run "one" (and "two") since there is no dependencies array.
|
||||
'useLayoutEffect unmount "one"',
|
||||
'useLayoutEffect mount "one"',
|
||||
'useLayoutEffect mount "two"',
|
||||
|
||||
// Since "two" is new, it should be double-invoked.
|
||||
'useLayoutEffect unmount "two"',
|
||||
'useLayoutEffect mount "two"',
|
||||
]);
|
||||
expect(log).toEqual([
|
||||
// Cleanup and re-run "one" (and "two") since there is no dependencies array.
|
||||
'useLayoutEffect unmount "one"',
|
||||
'useLayoutEffect mount "one"',
|
||||
'useLayoutEffect mount "two"',
|
||||
|
||||
// Since "two" is new, it should be double-invoked.
|
||||
'useLayoutEffect unmount "two"',
|
||||
'useLayoutEffect mount "two"',
|
||||
@@ -142,15 +163,24 @@ describe('StrictEffectsMode defaults', () => {
|
||||
// This test also verifies that double-invoked effects flush synchronously
|
||||
// within the same frame as passive effects.
|
||||
it('should double invoke effects only for newly mounted components', async () => {
|
||||
const log = [];
|
||||
function ComponentWithEffects({label}) {
|
||||
React.useEffect(() => {
|
||||
log.push(`useEffect mount "${label}"`);
|
||||
Scheduler.log(`useEffect mount "${label}"`);
|
||||
return () => Scheduler.log(`useEffect unmount "${label}"`);
|
||||
return () => {
|
||||
log.push(`useEffect unmount "${label}"`);
|
||||
Scheduler.log(`useEffect unmount "${label}"`);
|
||||
};
|
||||
});
|
||||
|
||||
React.useLayoutEffect(() => {
|
||||
log.push(`useLayoutEffect mount "${label}"`);
|
||||
Scheduler.log(`useLayoutEffect mount "${label}"`);
|
||||
return () => Scheduler.log(`useLayoutEffect unmount "${label}"`);
|
||||
return () => {
|
||||
log.push(`useLayoutEffect unmount "${label}"`);
|
||||
Scheduler.log(`useLayoutEffect unmount "${label}"`);
|
||||
};
|
||||
});
|
||||
|
||||
return label;
|
||||
@@ -171,8 +201,17 @@ describe('StrictEffectsMode defaults', () => {
|
||||
'useLayoutEffect mount "one"',
|
||||
'useEffect mount "one"',
|
||||
]);
|
||||
expect(log).toEqual([
|
||||
'useLayoutEffect mount "one"',
|
||||
'useEffect mount "one"',
|
||||
'useLayoutEffect unmount "one"',
|
||||
'useEffect unmount "one"',
|
||||
'useLayoutEffect mount "one"',
|
||||
'useEffect mount "one"',
|
||||
]);
|
||||
});
|
||||
|
||||
log.length = 0;
|
||||
await act(async () => {
|
||||
ReactNoop.render(
|
||||
<React.StrictMode>
|
||||
@@ -187,11 +226,29 @@ describe('StrictEffectsMode defaults', () => {
|
||||
'useLayoutEffect mount "one"',
|
||||
'useLayoutEffect mount "two"',
|
||||
]);
|
||||
expect(log).toEqual([
|
||||
// Cleanup and re-run "one" (and "two") since there is no dependencies array.
|
||||
'useLayoutEffect unmount "one"',
|
||||
'useLayoutEffect mount "one"',
|
||||
'useLayoutEffect mount "two"',
|
||||
]);
|
||||
log.length = 0;
|
||||
await waitForAll([
|
||||
'useEffect unmount "one"',
|
||||
'useEffect mount "one"',
|
||||
'useEffect mount "two"',
|
||||
|
||||
// Since "two" is new, it should be double-invoked.
|
||||
'useLayoutEffect unmount "two"',
|
||||
'useEffect unmount "two"',
|
||||
'useLayoutEffect mount "two"',
|
||||
'useEffect mount "two"',
|
||||
]);
|
||||
expect(log).toEqual([
|
||||
'useEffect unmount "one"',
|
||||
'useEffect mount "one"',
|
||||
'useEffect mount "two"',
|
||||
|
||||
// Since "two" is new, it should be double-invoked.
|
||||
'useLayoutEffect unmount "two"',
|
||||
'useEffect unmount "two"',
|
||||
@@ -202,15 +259,16 @@ describe('StrictEffectsMode defaults', () => {
|
||||
});
|
||||
|
||||
it('double invoking for effects for modern roots', async () => {
|
||||
const log = [];
|
||||
function App({text}) {
|
||||
React.useEffect(() => {
|
||||
Scheduler.log('useEffect mount');
|
||||
return () => Scheduler.log('useEffect unmount');
|
||||
log.push('useEffect mount');
|
||||
return () => log.push('useEffect unmount');
|
||||
});
|
||||
|
||||
React.useLayoutEffect(() => {
|
||||
Scheduler.log('useLayoutEffect mount');
|
||||
return () => Scheduler.log('useLayoutEffect unmount');
|
||||
log.push('useLayoutEffect mount');
|
||||
return () => log.push('useLayoutEffect unmount');
|
||||
});
|
||||
|
||||
return text;
|
||||
@@ -223,7 +281,7 @@ describe('StrictEffectsMode defaults', () => {
|
||||
);
|
||||
});
|
||||
|
||||
assertLog([
|
||||
expect(log).toEqual([
|
||||
'useLayoutEffect mount',
|
||||
'useEffect mount',
|
||||
'useLayoutEffect unmount',
|
||||
@@ -232,6 +290,7 @@ describe('StrictEffectsMode defaults', () => {
|
||||
'useEffect mount',
|
||||
]);
|
||||
|
||||
log.length = 0;
|
||||
await act(() => {
|
||||
ReactNoop.render(
|
||||
<React.StrictMode>
|
||||
@@ -240,30 +299,32 @@ describe('StrictEffectsMode defaults', () => {
|
||||
);
|
||||
});
|
||||
|
||||
assertLog([
|
||||
expect(log).toEqual([
|
||||
'useLayoutEffect unmount',
|
||||
'useLayoutEffect mount',
|
||||
'useEffect unmount',
|
||||
'useEffect mount',
|
||||
]);
|
||||
|
||||
log.length = 0;
|
||||
await act(() => {
|
||||
ReactNoop.render(null);
|
||||
});
|
||||
|
||||
assertLog(['useLayoutEffect unmount', 'useEffect unmount']);
|
||||
expect(log).toEqual(['useLayoutEffect unmount', 'useEffect unmount']);
|
||||
});
|
||||
|
||||
it('multiple effects are double invoked in the right order (all mounted, all unmounted, all remounted)', async () => {
|
||||
const log = [];
|
||||
function App({text}) {
|
||||
React.useEffect(() => {
|
||||
Scheduler.log('useEffect One mount');
|
||||
return () => Scheduler.log('useEffect One unmount');
|
||||
log.push('useEffect One mount');
|
||||
return () => log.push('useEffect One unmount');
|
||||
});
|
||||
|
||||
React.useEffect(() => {
|
||||
Scheduler.log('useEffect Two mount');
|
||||
return () => Scheduler.log('useEffect Two unmount');
|
||||
log.push('useEffect Two mount');
|
||||
return () => log.push('useEffect Two unmount');
|
||||
});
|
||||
|
||||
return text;
|
||||
@@ -277,7 +338,7 @@ describe('StrictEffectsMode defaults', () => {
|
||||
);
|
||||
});
|
||||
|
||||
assertLog([
|
||||
expect(log).toEqual([
|
||||
'useEffect One mount',
|
||||
'useEffect Two mount',
|
||||
'useEffect One unmount',
|
||||
@@ -286,6 +347,7 @@ describe('StrictEffectsMode defaults', () => {
|
||||
'useEffect Two mount',
|
||||
]);
|
||||
|
||||
log.length = 0;
|
||||
await act(() => {
|
||||
ReactNoop.render(
|
||||
<React.StrictMode>
|
||||
@@ -294,30 +356,32 @@ describe('StrictEffectsMode defaults', () => {
|
||||
);
|
||||
});
|
||||
|
||||
assertLog([
|
||||
expect(log).toEqual([
|
||||
'useEffect One unmount',
|
||||
'useEffect Two unmount',
|
||||
'useEffect One mount',
|
||||
'useEffect Two mount',
|
||||
]);
|
||||
|
||||
log.length = 0;
|
||||
await act(() => {
|
||||
ReactNoop.render(null);
|
||||
});
|
||||
|
||||
assertLog(['useEffect One unmount', 'useEffect Two unmount']);
|
||||
expect(log).toEqual(['useEffect One unmount', 'useEffect Two unmount']);
|
||||
});
|
||||
|
||||
it('multiple layout effects are double invoked in the right order (all mounted, all unmounted, all remounted)', async () => {
|
||||
const log = [];
|
||||
function App({text}) {
|
||||
React.useLayoutEffect(() => {
|
||||
Scheduler.log('useLayoutEffect One mount');
|
||||
return () => Scheduler.log('useLayoutEffect One unmount');
|
||||
log.push('useLayoutEffect One mount');
|
||||
return () => log.push('useLayoutEffect One unmount');
|
||||
});
|
||||
|
||||
React.useLayoutEffect(() => {
|
||||
Scheduler.log('useLayoutEffect Two mount');
|
||||
return () => Scheduler.log('useLayoutEffect Two unmount');
|
||||
log.push('useLayoutEffect Two mount');
|
||||
return () => log.push('useLayoutEffect Two unmount');
|
||||
});
|
||||
|
||||
return text;
|
||||
@@ -331,7 +395,7 @@ describe('StrictEffectsMode defaults', () => {
|
||||
);
|
||||
});
|
||||
|
||||
assertLog([
|
||||
expect(log).toEqual([
|
||||
'useLayoutEffect One mount',
|
||||
'useLayoutEffect Two mount',
|
||||
'useLayoutEffect One unmount',
|
||||
@@ -340,6 +404,7 @@ describe('StrictEffectsMode defaults', () => {
|
||||
'useLayoutEffect Two mount',
|
||||
]);
|
||||
|
||||
log.length = 0;
|
||||
await act(() => {
|
||||
ReactNoop.render(
|
||||
<React.StrictMode>
|
||||
@@ -348,28 +413,33 @@ describe('StrictEffectsMode defaults', () => {
|
||||
);
|
||||
});
|
||||
|
||||
assertLog([
|
||||
expect(log).toEqual([
|
||||
'useLayoutEffect One unmount',
|
||||
'useLayoutEffect Two unmount',
|
||||
'useLayoutEffect One mount',
|
||||
'useLayoutEffect Two mount',
|
||||
]);
|
||||
|
||||
log.length = 0;
|
||||
await act(() => {
|
||||
ReactNoop.render(null);
|
||||
});
|
||||
|
||||
assertLog(['useLayoutEffect One unmount', 'useLayoutEffect Two unmount']);
|
||||
expect(log).toEqual([
|
||||
'useLayoutEffect One unmount',
|
||||
'useLayoutEffect Two unmount',
|
||||
]);
|
||||
});
|
||||
|
||||
it('useEffect and useLayoutEffect is called twice when there is no unmount', async () => {
|
||||
const log = [];
|
||||
function App({text}) {
|
||||
React.useEffect(() => {
|
||||
Scheduler.log('useEffect mount');
|
||||
log.push('useEffect mount');
|
||||
});
|
||||
|
||||
React.useLayoutEffect(() => {
|
||||
Scheduler.log('useLayoutEffect mount');
|
||||
log.push('useLayoutEffect mount');
|
||||
});
|
||||
|
||||
return text;
|
||||
@@ -383,13 +453,14 @@ describe('StrictEffectsMode defaults', () => {
|
||||
);
|
||||
});
|
||||
|
||||
assertLog([
|
||||
expect(log).toEqual([
|
||||
'useLayoutEffect mount',
|
||||
'useEffect mount',
|
||||
'useLayoutEffect mount',
|
||||
'useEffect mount',
|
||||
]);
|
||||
|
||||
log.length = 0;
|
||||
await act(() => {
|
||||
ReactNoop.render(
|
||||
<React.StrictMode>
|
||||
@@ -398,13 +469,14 @@ describe('StrictEffectsMode defaults', () => {
|
||||
);
|
||||
});
|
||||
|
||||
assertLog(['useLayoutEffect mount', 'useEffect mount']);
|
||||
expect(log).toEqual(['useLayoutEffect mount', 'useEffect mount']);
|
||||
|
||||
log.length = 0;
|
||||
await act(() => {
|
||||
ReactNoop.render(null);
|
||||
});
|
||||
|
||||
assertLog([]);
|
||||
expect(log).toEqual([]);
|
||||
});
|
||||
|
||||
//@gate useModernStrictMode
|
||||
@@ -436,22 +508,23 @@ describe('StrictEffectsMode defaults', () => {
|
||||
});
|
||||
|
||||
it('passes the right context to class component lifecycles', async () => {
|
||||
const log = [];
|
||||
class App extends React.PureComponent {
|
||||
test() {}
|
||||
|
||||
componentDidMount() {
|
||||
this.test();
|
||||
Scheduler.log('componentDidMount');
|
||||
log.push('componentDidMount');
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
this.test();
|
||||
Scheduler.log('componentDidUpdate');
|
||||
log.push('componentDidUpdate');
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.test();
|
||||
Scheduler.log('componentWillUnmount');
|
||||
log.push('componentWillUnmount');
|
||||
}
|
||||
|
||||
render() {
|
||||
@@ -467,7 +540,7 @@ describe('StrictEffectsMode defaults', () => {
|
||||
);
|
||||
});
|
||||
|
||||
assertLog([
|
||||
expect(log).toEqual([
|
||||
'componentDidMount',
|
||||
'componentWillUnmount',
|
||||
'componentDidMount',
|
||||
@@ -475,17 +548,18 @@ describe('StrictEffectsMode defaults', () => {
|
||||
});
|
||||
|
||||
it('double invoking works for class components', async () => {
|
||||
const log = [];
|
||||
class App extends React.PureComponent {
|
||||
componentDidMount() {
|
||||
Scheduler.log('componentDidMount');
|
||||
log.push('componentDidMount');
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
Scheduler.log('componentDidUpdate');
|
||||
log.push('componentDidUpdate');
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
Scheduler.log('componentWillUnmount');
|
||||
log.push('componentWillUnmount');
|
||||
}
|
||||
|
||||
render() {
|
||||
@@ -501,12 +575,13 @@ describe('StrictEffectsMode defaults', () => {
|
||||
);
|
||||
});
|
||||
|
||||
assertLog([
|
||||
expect(log).toEqual([
|
||||
'componentDidMount',
|
||||
'componentWillUnmount',
|
||||
'componentDidMount',
|
||||
]);
|
||||
|
||||
log.length = 0;
|
||||
await act(() => {
|
||||
ReactNoop.render(
|
||||
<React.StrictMode>
|
||||
@@ -515,35 +590,38 @@ describe('StrictEffectsMode defaults', () => {
|
||||
);
|
||||
});
|
||||
|
||||
assertLog(['componentDidUpdate']);
|
||||
expect(log).toEqual(['componentDidUpdate']);
|
||||
|
||||
log.length = 0;
|
||||
await act(() => {
|
||||
ReactNoop.render(null);
|
||||
});
|
||||
|
||||
assertLog(['componentWillUnmount']);
|
||||
expect(log).toEqual(['componentWillUnmount']);
|
||||
});
|
||||
|
||||
it('double flushing passive effects only results in one double invoke', async () => {
|
||||
const log = [];
|
||||
function App({text}) {
|
||||
const [state, setState] = React.useState(0);
|
||||
React.useEffect(() => {
|
||||
if (state !== 1) {
|
||||
setState(1);
|
||||
}
|
||||
Scheduler.log('useEffect mount');
|
||||
return () => Scheduler.log('useEffect unmount');
|
||||
log.push('useEffect mount');
|
||||
return () => log.push('useEffect unmount');
|
||||
});
|
||||
|
||||
React.useLayoutEffect(() => {
|
||||
Scheduler.log('useLayoutEffect mount');
|
||||
return () => Scheduler.log('useLayoutEffect unmount');
|
||||
log.push('useLayoutEffect mount');
|
||||
return () => log.push('useLayoutEffect unmount');
|
||||
});
|
||||
|
||||
Scheduler.log(text);
|
||||
log.push(text);
|
||||
return text;
|
||||
}
|
||||
|
||||
log.length = 0;
|
||||
await act(() => {
|
||||
ReactNoop.render(
|
||||
<React.StrictMode>
|
||||
@@ -552,7 +630,8 @@ describe('StrictEffectsMode defaults', () => {
|
||||
);
|
||||
});
|
||||
|
||||
assertLog([
|
||||
expect(log).toEqual([
|
||||
'mount',
|
||||
'mount',
|
||||
'useLayoutEffect mount',
|
||||
'useEffect mount',
|
||||
@@ -561,6 +640,7 @@ describe('StrictEffectsMode defaults', () => {
|
||||
'useLayoutEffect mount',
|
||||
'useEffect mount',
|
||||
'mount',
|
||||
'mount',
|
||||
'useLayoutEffect unmount',
|
||||
'useLayoutEffect mount',
|
||||
'useEffect unmount',
|
||||
@@ -570,14 +650,15 @@ describe('StrictEffectsMode defaults', () => {
|
||||
|
||||
it('newly mounted components after initial mount get double invoked', async () => {
|
||||
let _setShowChild;
|
||||
const log = [];
|
||||
function Child() {
|
||||
React.useEffect(() => {
|
||||
Scheduler.log('Child useEffect mount');
|
||||
return () => Scheduler.log('Child useEffect unmount');
|
||||
log.push('Child useEffect mount');
|
||||
return () => log.push('Child useEffect unmount');
|
||||
});
|
||||
React.useLayoutEffect(() => {
|
||||
Scheduler.log('Child useLayoutEffect mount');
|
||||
return () => Scheduler.log('Child useLayoutEffect unmount');
|
||||
log.push('Child useLayoutEffect mount');
|
||||
return () => log.push('Child useLayoutEffect unmount');
|
||||
});
|
||||
|
||||
return null;
|
||||
@@ -587,12 +668,12 @@ describe('StrictEffectsMode defaults', () => {
|
||||
const [showChild, setShowChild] = React.useState(false);
|
||||
_setShowChild = setShowChild;
|
||||
React.useEffect(() => {
|
||||
Scheduler.log('App useEffect mount');
|
||||
return () => Scheduler.log('App useEffect unmount');
|
||||
log.push('App useEffect mount');
|
||||
return () => log.push('App useEffect unmount');
|
||||
});
|
||||
React.useLayoutEffect(() => {
|
||||
Scheduler.log('App useLayoutEffect mount');
|
||||
return () => Scheduler.log('App useLayoutEffect unmount');
|
||||
log.push('App useLayoutEffect mount');
|
||||
return () => log.push('App useLayoutEffect unmount');
|
||||
});
|
||||
|
||||
return showChild && <Child />;
|
||||
@@ -606,7 +687,7 @@ describe('StrictEffectsMode defaults', () => {
|
||||
);
|
||||
});
|
||||
|
||||
assertLog([
|
||||
expect(log).toEqual([
|
||||
'App useLayoutEffect mount',
|
||||
'App useEffect mount',
|
||||
'App useLayoutEffect unmount',
|
||||
@@ -615,11 +696,12 @@ describe('StrictEffectsMode defaults', () => {
|
||||
'App useEffect mount',
|
||||
]);
|
||||
|
||||
log.length = 0;
|
||||
await act(() => {
|
||||
_setShowChild(true);
|
||||
});
|
||||
|
||||
assertLog([
|
||||
expect(log).toEqual([
|
||||
'App useLayoutEffect unmount',
|
||||
'Child useLayoutEffect mount',
|
||||
'App useLayoutEffect mount',
|
||||
@@ -634,13 +716,14 @@ describe('StrictEffectsMode defaults', () => {
|
||||
});
|
||||
|
||||
it('classes and functions are double invoked together correctly', async () => {
|
||||
const log = [];
|
||||
class ClassChild extends React.PureComponent {
|
||||
componentDidMount() {
|
||||
Scheduler.log('componentDidMount');
|
||||
log.push('componentDidMount');
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
Scheduler.log('componentWillUnmount');
|
||||
log.push('componentWillUnmount');
|
||||
}
|
||||
|
||||
render() {
|
||||
@@ -650,12 +733,12 @@ describe('StrictEffectsMode defaults', () => {
|
||||
|
||||
function FunctionChild({text}) {
|
||||
React.useEffect(() => {
|
||||
Scheduler.log('useEffect mount');
|
||||
return () => Scheduler.log('useEffect unmount');
|
||||
log.push('useEffect mount');
|
||||
return () => log.push('useEffect unmount');
|
||||
});
|
||||
React.useLayoutEffect(() => {
|
||||
Scheduler.log('useLayoutEffect mount');
|
||||
return () => Scheduler.log('useLayoutEffect unmount');
|
||||
log.push('useLayoutEffect mount');
|
||||
return () => log.push('useLayoutEffect unmount');
|
||||
});
|
||||
return text;
|
||||
}
|
||||
@@ -677,7 +760,7 @@ describe('StrictEffectsMode defaults', () => {
|
||||
);
|
||||
});
|
||||
|
||||
assertLog([
|
||||
expect(log).toEqual([
|
||||
'componentDidMount',
|
||||
'useLayoutEffect mount',
|
||||
'useEffect mount',
|
||||
@@ -689,6 +772,7 @@ describe('StrictEffectsMode defaults', () => {
|
||||
'useEffect mount',
|
||||
]);
|
||||
|
||||
log.length = 0;
|
||||
await act(() => {
|
||||
ReactNoop.render(
|
||||
<React.StrictMode>
|
||||
@@ -697,18 +781,19 @@ describe('StrictEffectsMode defaults', () => {
|
||||
);
|
||||
});
|
||||
|
||||
assertLog([
|
||||
expect(log).toEqual([
|
||||
'useLayoutEffect unmount',
|
||||
'useLayoutEffect mount',
|
||||
'useEffect unmount',
|
||||
'useEffect mount',
|
||||
]);
|
||||
|
||||
log.length = 0;
|
||||
await act(() => {
|
||||
ReactNoop.render(null);
|
||||
});
|
||||
|
||||
assertLog([
|
||||
expect(log).toEqual([
|
||||
'componentWillUnmount',
|
||||
'useLayoutEffect unmount',
|
||||
'useEffect unmount',
|
||||
|
||||
Reference in New Issue
Block a user