motiondivision / motion

A modern animation library for React and JavaScript
https://motion.dev
MIT License
25.84k stars 849 forks source link

[BUG] `AnimatePresence` rerender bug (needs repro) #2743

Closed ArianHamdi closed 4 months ago

ArianHamdi commented 4 months ago

There is a breaking change in version 11.3.18 related to <AnimatePresence />.

I'll create a code sandbox likely by tomorrow, but I've created this issue to inform others about this bug so they can downgrade their framer-motion version.

According to the changelog, there has been a significant refactor in <AnimatePresence/>, which is not suitable for a patch version. I don't want to blame anyone here, but when you publish something as a patch level, the package manager will automatically install this version, potentially causing serious issues.

Packages:

next: 14.2.5 react: ^18 framer-motion: 11.3.18 framer-motion-3d: 11.3.18

Anyway, thanks for your amazing library, and happy coding!

AnYiEE commented 4 months ago

I can reproduce it. My application uses NextUI, when the framer-motion version is upgraded from 11.3.8 to 11.3.18, some components cannot be re-rendered normally (such as the check mark when an option is selected in the DropdownMenu), rolling back to 11.3.8 or upgrading to 11.3.17 everything is normal.

ahbyass commented 4 months ago

I can also reproduce, style changes were not being passed to child component of AnimatePresence. Reverting to previous version is working.

gurkerl83 commented 4 months ago

Seeing a similar thing. We use variants receiving props with the custom prop, but in the new version no custom props are passed to the respective variant anymore. Another thing is that awaiting an animation and starting another is completely broken, they do not even start anymore, but all these effects are maybe related because the cloneElement was replaced with a different approach. Anyway there is something really wired going on, when I have time next week I will also try to replicate this behavior in a sandbox.

dev-aly3n commented 4 months ago

same here. the conditional rendering inside AnimatePresence doesnt work as expected.

mattgperry commented 4 months ago

Can someone please provide a reproduction? I feel like there’s a couple things being reported here and for any one thing to be fixed it’ll be less likely to be overlooked and quicker to be fixed with a repro. Thanks!

Also I appreciate that it’s annoying that this broke in a patch but it was a refactor that only fixed bugs, not introducing new functionality, any code change could introduce bugs so it wouldn’t have been appropriate to use a minor version.

mattgperry commented 4 months ago

Ah I think I see what you're getting at.


export const App = () => {
    const [key, setKey] = useState("a")

    console.log(key === "a" ? "green" : "blue")

    return (
        <div
            onClick={() => {
                setKey(key === "a" ? "b" : "a")
            }}
        >
            <AnimatePresence
                initial={false}
                onExitComplete={() => console.log("rest")}
            >
                <motion.div
                    // key={key}
                    initial={{ opacity: 0 }}
                    animate={{ opacity: 1 }}
                    exit={{ opacity: 0 }}
                    transition={{ duration: 1 }}
                    style={{
                        ...style,
                        backgroundColor: key === "a" ? "green" : "blue",
                    }}
                />
            </AnimatePresence>
        </div>
    )
}

Normal re-renders when present hasn't changed are not working. Will look into it.

mattgperry commented 4 months ago

I believe I have a fix, probably for everything mentioned above, going out as 11.3.19 now (available in 15 min)

If issues still persist please open a new ticket and I'll take a look next week!