From d7d4cd9faf69ad6d0af9e6403aca2738055c5051 Mon Sep 17 00:00:00 2001 From: AMin Date: Sun, 25 Oct 2026 14:04:37 +0800 Subject: [PATCH 1/2] fix(SwitchTransition): reset status when children are removed --- src/SwitchTransition.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/SwitchTransition.js b/src/SwitchTransition.js index 78dc375d..2a5cb61a 100644 --- a/src/SwitchTransition.js +++ b/src/SwitchTransition.js @@ -143,6 +143,7 @@ class SwitchTransition extends React.Component { static getDerivedStateFromProps(props, state) { if (props.children == null) { return { + status: ENTERED, current: null, }; } From 80dde81c0788753cc22e4f39b6a116747546fd91 Mon Sep 17 00:00:00 2001 From: AMin Date: Sun, 25 Oct 2026 14:05:40 +0800 Subject: [PATCH 2/2] test(SwitchTransition): cover removing children during transitions --- test/SwitchTransition-test.js | 43 +++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/test/SwitchTransition-test.js b/test/SwitchTransition-test.js index 9250a586..42c35807 100644 --- a/test/SwitchTransition-test.js +++ b/test/SwitchTransition-test.js @@ -157,4 +157,47 @@ describe('SwitchTransition', () => { expect(container.textContent).toBe('second'); }); + + it.each([ + ['out-in', 'exiting'], + ['out-in', 'entering'], + ['in-out', 'entering'], + ['in-out', 'exiting'], + ])('handles null children in %s mode while %s', (mode, status) => { + const firstRef = React.createRef(); + const secondRef = React.createRef(); + const first = ( + + {(state) => first: {state}} + + ); + const second = ( + + {(state) => second: {state}} + + ); + const { container, rerender } = render( + {first} + ); + + rerender({second}); + if (status === (mode === 'out-in' ? 'entering' : 'exiting')) { + act(() => { + jest.runOnlyPendingTimers(); + }); + } + expect(container.textContent).toContain(status); + + rerender({null}); + act(() => { + jest.runAllTimers(); + }); + expect(container.textContent).toBe(''); + + rerender({first}); + act(() => { + jest.runAllTimers(); + }); + expect(container.textContent).toBe('first: entered'); + }); });