diff --git a/packages/react-reconciler/src/__tests__/ReactSuspense-test.internal.js b/packages/react-reconciler/src/__tests__/ReactSuspense-test.internal.js
index a5db0b503612..f8d0a704d3d7 100644
--- a/packages/react-reconciler/src/__tests__/ReactSuspense-test.internal.js
+++ b/packages/react-reconciler/src/__tests__/ReactSuspense-test.internal.js
@@ -663,6 +663,53 @@ describe('ReactSuspense', () => {
expect(root).toMatchRenderedOutput('new value');
});
+ // @gate enableSuspenseLayoutEffectSemantics
+ it('re-fires layout effects when re-showing Suspense', () => {
+ function TextWithLayout(props) {
+ Scheduler.unstable_yieldValue(props.text);
+ React.useLayoutEffect(() => {
+ Scheduler.unstable_yieldValue('create layout');
+ return () => {
+ Scheduler.unstable_yieldValue('destroy layout');
+ };
+ }, []);
+ return props.text;
+ }
+
+ let _setShow;
+ function App(props) {
+ const [show, setShow] = React.useState(false);
+ _setShow = setShow;
+ return (
+ }>
+
+ {show && }
+
+ );
+ }
+
+ const root = ReactTestRenderer.create(, {
+ unstable_isConcurrent: true,
+ });
+
+ expect(Scheduler).toFlushAndYield(['Child 1', 'create layout']);
+ expect(root).toMatchRenderedOutput('Child 1');
+
+ ReactTestRenderer.act(() => {
+ _setShow(true);
+ });
+ expect(Scheduler).toHaveYielded([
+ 'Child 1',
+ 'Suspend! [Child 2]',
+ 'Loading...',
+ 'destroy layout',
+ ]);
+ jest.advanceTimersByTime(1000);
+ expect(Scheduler).toHaveYielded(['Promise resolved [Child 2]']);
+ expect(Scheduler).toFlushAndYield(['Child 1', 'Child 2', 'create layout']);
+ expect(root).toMatchRenderedOutput(['Child 1', 'Child 2'].join(''));
+ });
+
describe('outside concurrent mode', () => {
it('a mounted class component can suspend without losing state', () => {
class TextWithLifecycle extends React.Component {