-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
Note
Motion for Vue issues: Please open in the Motion for Vue repo.
1. Read the FAQs 👇
2. Describe the bug
When using AnimatePresence, updating the custom prop on a component while keeping the same key causes an unwanted style update/merge.
Instead of ignoring the custom prop change (since the component is technically the same and hasn't re-mounted), Framer Motion attempts to apply the variant associated with the new custom value. This results in the new styles being applied while the previous variant's styles are not correctly cleaned up, leading to a corrupted UI state (style bleeding).
3. IMPORTANT: Provide a CodeSandbox reproduction of the bug
https://codesandbox.io/p/sandbox/unexited-animatepresence-child-forked-5vy49s
4. Steps to reproduce
Steps to reproduce the behavior:
- Open the provided CodeSandbox link.
- Click the "Move" button once to advance to "Current Index: 1".
- Note: In this reproduction, Index 0 and Index 1 share the exact same
key, but have differentcustomvalues which drive different dynamic variants.
- Note: In this reproduction, Index 0 and Index 1 share the exact same
- Observe the "Current Style" log text below the button.
- See error: The log shows that the styles from the previous custom value (Index 0) persist and are merged with the styles of the new custom value (Index 1), creating an incorrect visual state.
5. Expected behavior
Changes to the custom prop while the key remains the same should be ignored regarding variant selection/animation.
The component should not re-animate or apply new variant values based on the updated custom prop while it is mounted. It should maintain the state established upon mounting (or the last successful key change). A change in custom without a change in key should not trigger a visual update or style recalculation.
6. Video or screenshots
N/A
7. Environment details
CodeSandbox & Local Environment:
- React: 18.2.0 (Sandbox) / 19.2.3 (Local)
- Motion:
12.34.0-alpha.0(Both) - Browser: Zen (Firefox based) & Microsoft Edge
- OS: Windows 11
FAQs
React Server Components "use client" error
If you're importing motion or m into a React Server Component environment, ensure you're importing from motion/react-client instead of motion/react.
import * as motion from "motion/react-client"
import * as m from "framer-motion/react-m"Motion for React won't install
Different versions of Motion for React are compatible with different versions of React.
React 19: framer-motion@12.0.0-alpha.0 or higher
React 18: framer-motion@7.0.0 to framer-motion@11.x, or motion
React 17: framer-motion@6.x or lower
height: "auto" is jumping
Animating to/from auto requires measuring the DOM. There's no perfect way to do this and if you have also applied padding to the same element, these measurements might be wrong.
The recommended solution is to move padding to a child element. See this issue for the full discussion.
Preact isn't working
Motion for React isn't compatible with Preact.
AnimatePresence isn't working
Have all of its immediate children got a unique key prop that remains the same for that component every render?
// Bad: The index could be given to a different component if the order of items changes
<AnimatePresence>
{items.map((item, index) => (
<Component key={index} />
))}
</AnimatePresence>// Good: The item ID is unique to each component
<AnimatePresence>
{items.map((item, index) => (
<Component key={item.id} />
))}
</AnimatePresence>Is the AnimatePresence correctly outside of the controlling conditional? AnimatePresence must be rendered whenever you expect an exit animation to run - it can't do so if it's unmounted!
// Bad: AnimatePresence is unmounted - exit animations won't run
{
isVisible && (
<AnimatePresence>
<Component />
</AnimatePresence>
)
}// Good: Only the children are unmounted - exit animations will run
<AnimatePresence>{isVisible && <Component />}</AnimatePresence>