From 0668c800a6ba86b783e3fc51ee6232661cbc8be7 Mon Sep 17 00:00:00 2001 From: Matt Perry Date: Sat, 27 Jul 2024 14:15:12 +0200 Subject: [PATCH] Fixing `AnimatePresence` rerenders (#2744) * Adding failing tests * Fixing rerender * Undoing test changes --- .../__tests__/AnimatePresence.test.tsx | 15 +++++++++++++++ .../src/components/AnimatePresence/index.tsx | 14 ++------------ .../src/components/AnimatePresence/utils.ts | 10 ---------- 3 files changed, 17 insertions(+), 22 deletions(-) diff --git a/packages/framer-motion/src/components/AnimatePresence/__tests__/AnimatePresence.test.tsx b/packages/framer-motion/src/components/AnimatePresence/__tests__/AnimatePresence.test.tsx index 385c2679ed..5b4134d2d3 100644 --- a/packages/framer-motion/src/components/AnimatePresence/__tests__/AnimatePresence.test.tsx +++ b/packages/framer-motion/src/components/AnimatePresence/__tests__/AnimatePresence.test.tsx @@ -71,6 +71,21 @@ describe("AnimatePresence", () => { expect(element).toHaveStyle("transform: translateX(100px)") }) + test("Normal rerenders work as expected", async () => { + const Component = ({ color }: { color: string }) => { + return ( + +
+ + ) + } + + const { container, rerender } = render() + rerender() + + expect(container.firstChild).toHaveStyle("background-color: green") + }) + test("Animates out a component when its removed", async () => { const opacity = motionValue(1) diff --git a/packages/framer-motion/src/components/AnimatePresence/index.tsx b/packages/framer-motion/src/components/AnimatePresence/index.tsx index 7479795c12..152f05754e 100644 --- a/packages/framer-motion/src/components/AnimatePresence/index.tsx +++ b/packages/framer-motion/src/components/AnimatePresence/index.tsx @@ -6,7 +6,7 @@ import { LayoutGroupContext } from "../../context/LayoutGroupContext" import { invariant } from "../../utils/errors" import { useIsomorphicLayoutEffect } from "../../three-entry" import { useConstant } from "../../utils/use-constant" -import { ComponentKey, arrayEquals, getChildKey, onlyElements } from "./utils" +import { ComponentKey, getChildKey, onlyElements } from "./utils" /** * `AnimatePresence` enables the animation of components that have been removed from the tree. @@ -137,17 +137,7 @@ export const AnimatePresence: React.FunctionComponent< nextChildren = exitingChildren } - nextChildren = onlyElements(nextChildren) - - const childrenHaveChanged = !arrayEquals( - nextChildren.map(getChildKey), - renderedChildren.map(getChildKey) - ) - - if (childrenHaveChanged) { - setRenderedChildren(nextChildren) - } - + setRenderedChildren(onlyElements(nextChildren)) setDiffedChildren(presentChildren) /** diff --git a/packages/framer-motion/src/components/AnimatePresence/utils.ts b/packages/framer-motion/src/components/AnimatePresence/utils.ts index 6e3630b347..5a51cae023 100644 --- a/packages/framer-motion/src/components/AnimatePresence/utils.ts +++ b/packages/framer-motion/src/components/AnimatePresence/utils.ts @@ -15,13 +15,3 @@ export function onlyElements(children: ReactNode): ReactElement[] { return filtered } - -export function arrayEquals(a: any[], b: any[]) { - if (a.length !== b.length) return false - - for (let i = 0; i < a.length; i++) { - if (a[i] !== b[i]) return false - } - - return true -}