One of framer-motion's coolest features is the ability to natively animate elements into, and out of, the page.
It's called AnimatePresence
and it's a React component that you can import like so:
import { AnimatePresence } from "framer-motion"
🏃♂️ Get started with AnimatePresence
We can use AnimatePresence
to check if a motion
component should play an entry or exit animation based on some React state. It's a bit weird, but the general syntax looks like this:
<AnimatePresence>
{state && (
<motion.div key={...} initial={...} animate={...} exit={...} />
)}
</AnimatePresence>
You'll notice our familiar initial
and animate
props as well as some new props like key
and exit
, let's break them down real quick:
initial
will set the initial state of the animation, you can think of this as where the element should be before it enters the pageanimate
is the actual entry animation you want to playexit
is now the opposite ofanimate
and it tells framer-motion how the component should exit the pagekey
is a unique identifier (typically a string) that framer-motion uses to track animation state while transitioning amotion
component into/out of the DOM
🔎 How AnimatePresence
plays intro/exit animations
AnimatePresence
is a wrapper component that you can imagine as a pair of eyes (👀) that keeps track of whatever motion
components you define within it. The "key" here is the key
prop (heh). It tells framer-motion where the motion
component is within its lifecycle.
The second part to this equation is the React state that conditionally renders the motion
component. This is where the power of framer-motion and AnimatePresence
comes in: your animation plays its intro animation based on what's defined in animate
and if the component is being rendered into the DOM. Likewise, your exit animation plays based on what's defined in exit
and if your component is leaving the DOM.
AnimatePresence
will allow your exit animation to play before unmounting the component entirely (and deleting its markup from the client-side HTML).
🌲 Animating presence with multiple children
If you need to render an array of items (say a list and you want items rendered one-by-one) then you need to make sure you're using a key
that has a unique ID.
Given that, the syntax for adding multiple children is 1:1 with React:
<AnimatePresence>
{items.map((item, i) => (
<m.li key={i} initial={...} animate={...} exit={...}>
</m.li>
))}
</AnimatePresence>
Also keep in mind that you need to alter the array to conditionally render children into and out of the DOM!
⚙️ Configuring AnimatePresence
There are certain props you can pass into AnimatePresence
to customize its behavior.
The default configuration of this component should be good for 99% of use-cases, though I'll run over some edge cases where configuring the component can be helpful.
initial: boolean
Use initial={false}
if you want to use AnimatePresence
where the motion
component already exists on the page at runtime and you want to animate it out.
mode: "popLayout" | "sync"
The default value for mode is sync
, basically this means that multiple children within AnimatePresence
will animate into/out of the DOM on a one-by-one basis and the DOM layout will get updated as soon as the most recent animation stops playing. popLayout
is a more advanced use-case and it essentially allows for continuous layout changes as more children element either enter into the DOM or are taken out of it. For the most part, sync
is exactly what you want.
🎉 Final remarks
We've just taken a quick look at a very powerful component in framer-motion: AnimatePresence
. In the next tutorial we're going to cover an even more powerful feature of framer-motion. Stay tuned by subscribing below.