React State Transitions With Animations

A common challenge in React is managing state for components that have animations. For example, closing a modal after it transitions closed, resetting the state of a copy button after the animation finishes, or removing temporary height/width from expandable containers during open/close transitions.

There are a handful of approaches to solving these, including setTimeout, using libraries like framer-motion or react-transition-group, but many of these solutions involve a lot more runtime code, less performant animations, or inconsistent animation timing. Thankfully, the solution in most cases is a simple yet often forgotten technique: onAnimationEnd.

The onAnimationEnd event in React (animationend DOM event) allows you to wait for an animation to finish before executing some code. Using the example of a modal, you can wait for the close animation to finish before removing the modal from the DOM.

<div onAnimationEnd={() => removeModal()}>{/* ... */}</div>

What is great about this technique is that the timing is fully managed by the animation so you don’t have to sync a CSS animation with a JS timeout or similar. Everything just works no matter if the animation takes 100 milliseconds or 3 seconds.