Skip to content

[BUG] Animating after suspense fails with react compiler #3832

Description

@Pinpickle

1. Read the FAQs 👇

✅

2. Describe the bug

Animations interrupted with suspense are not resumed when the React Compiler is enabled.

Fairly simply:

<Suspense>
  <ComponentThatSuspends />
  <motion.div initial={{ opacity: 0 }} exit={{ opacity: 1 }} />
</Suspense>

When the React Compiler is enabled will cause the animation to stop and not re-play on re-mount.

This happens when the reference to motion.div is stable across re-renders (which the compiler enables) - so motion.div does not re-render. The test suite doesn't use the compiler, it just keeps the reference to motion.div stable.

3. IMPORTANT: Provide a CodeSandbox reproduction of the bug

https://stackblitz.com/edit/node-rczx2erx?file=suspense.test.tsx

The repro is AI-generated

4. Steps to reproduce

Run npm install and npm test in the Stackblitz link

5. Expected behavior

The re-mounted component ends up with opacity: 1 (all the tests pass)

Extra context

Adding this layout effect to useVisualElement appears to fix the issue with all tests passing

const hasConnectedOnce = useRef(false);
useIsomorphicLayoutEffect(() => {
  if (!hasConnectedOnce.current) {
    hasConnectedOnce.current = true;
    return;
  }
  visualElement.animationState?.animateChanges();
  visualElement.enteringChildren = undefined;
}, []);

Because layout effects re-run when suspense ends. I'm not confident enough with the internals to know whether this is OK or not.

This is a very similar bug to: #2269

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions