/
githubmr
/
facebook-react
Обзор
Документация
Войти
/
githubmr
/
facebook-react
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
main
packages/react-reconciler/src/__tests__/ActivityStrictMode-test.js
233 строки
5 KB
Ricky
Release Activity in Canary (#34374)
12 сен 2025, 19:47
Не верифицирован
12 сен 2025, 19:47
68f00c9
Код
Авторство
О чём код?
let React; let Activity; let ReactNoop; let act; let log; describe('Activity StrictMode', () => { beforeEach(() => { jest.resetModules(); log = []; React = require('react'); Activity = React.Activity; ReactNoop = require('react-noop-renderer'); act = require('internal-test-utils').act; }); function Component({label}) { React.useEffect(() => { log.push(`${label}: useEffect mount`); return () => log.push(`${label}: useEffect unmount`); }); React.useLayoutEffect(() => { log.push(`${label}: useLayoutEffect mount`); return () => log.push(`${label}: useLayoutEffect unmount`); }); log.push(`${label}: render`); return <span>label</span>; } // @gate __DEV__ && enableActivity it('should trigger strict effects when offscreen is visible', async () => { await act(() => { ReactNoop.render( <React.StrictMode> <Activity mode="visible"> <Component label="A" /> </Activity> </React.StrictMode>, ); }); expect(log).toEqual([ 'A: render', 'A: render', 'A: useLayoutEffect mount', 'A: useEffect mount', 'A: useLayoutEffect unmount', 'A: useEffect unmount', 'A: useLayoutEffect mount', 'A: useEffect mount', ]); }); // @gate __DEV__ && enableActivity it('should not trigger strict effects when offscreen is hidden', async () => { await act(() => { ReactNoop.render( <React.StrictMode> <Activity mode="hidden"> <Component label="A" /> </Activity> </React.StrictMode>, ); }); expect(log).toEqual(['A: render', 'A: render']); log = []; await act(() => { ReactNoop.render( <React.StrictMode> <Activity mode="hidden"> <Component label="A" /> <Component label="B" /> </Activity> </React.StrictMode>, ); }); expect(log).toEqual(['A: render', 'A: render', 'B: render', 'B: render']); log = []; await act(() => { ReactNoop.render( <React.StrictMode> <Activity mode="visible"> <Component label="A" /> </Activity> </React.StrictMode>, ); }); expect(log).toEqual([ 'A: render', 'A: render', 'A: useLayoutEffect mount', 'A: useEffect mount', 'A: useLayoutEffect unmount', 'A: useEffect unmount', 'A: useLayoutEffect mount', 'A: useEffect mount', ]); log = []; await act(() => { ReactNoop.render( <React.StrictMode> <Activity mode="hidden"> <Component label="A" /> </Activity> </React.StrictMode>, ); }); expect(log).toEqual([ 'A: useLayoutEffect unmount', 'A: useEffect unmount', 'A: render', 'A: render', ]); }); it('should not cause infinite render loop when StrictMode is used with Suspense and synchronous set states', async () => { // This is a regression test, see https://github.com/facebook/react/pull/25179 for more details. function App() { const [state, setState] = React.useState(false); React.useLayoutEffect(() => { setState(true); }, []); React.useEffect(() => { // Empty useEffect with empty dependency array is needed to trigger infinite render loop. }, []); return state; } await act(() => { ReactNoop.render( <React.StrictMode> <React.Suspense> <App /> </React.Suspense> </React.StrictMode>, ); }); }); // @gate __DEV__ && enableActivity it('should double invoke effects on unsuspended child', async () => { let shouldSuspend = true; let resolve; const suspensePromise = new Promise(_resolve => { resolve = _resolve; }); function Parent() { log.push('Parent rendered'); React.useEffect(() => { log.push('Parent mount'); return () => { log.push('Parent unmount'); }; }); return ( <React.Suspense fallback="fallback"> <Child /> </React.Suspense> ); } function Child() { log.push('Child rendered'); React.useEffect(() => { log.push('Child mount'); return () => { log.push('Child unmount'); }; }); if (shouldSuspend) { log.push('Child suspended'); throw suspensePromise; } return null; } await act(() => { ReactNoop.render( <React.StrictMode> <Activity mode="visible"> <Parent /> </Activity> </React.StrictMode>, ); }); log.push('------------------------------'); await act(() => { resolve(); shouldSuspend = false; }); expect(log).toEqual([ 'Parent rendered', 'Parent rendered', 'Child rendered', 'Child suspended', 'Parent mount', 'Parent unmount', 'Parent mount', // pre-warming 'Child rendered', 'Child suspended', // end pre-warming '------------------------------', 'Child rendered', 'Child rendered', 'Child mount', 'Child unmount', 'Child mount', ]); }); });