React Spring is a powerful and flexible animation library for React that provides a simple API to create smooth and interactive animations. It is based on physics-based animations, meaning that animations behave more naturally compared to traditional keyframe-based animations. React Spring can be used to create everything from simple animations to complex, interactive UIs.
This guide will walk you through how to get started with React Spring and use it to create smooth UI animations in your React applications.
1. Setting Up React Spring
Before you begin using React Spring, you need to install it in your React project.
npm install @react-spring/web
or, if using yarn:
yarn add @react-spring/web
2. Basic React Spring Animation
To create a basic animation with React Spring, you use the useSpring
hook to animate individual elements.
Example: Animating a Box
import React from 'react';
import { useSpring, animated } from '@react-spring/web';
const Box = () => {
// Define the animation
const props = useSpring({
from: { opacity: 0, transform: 'scale(0)' },
to: { opacity: 1, transform: 'scale(1)' },
config: { tension: 170, friction: 26 }, // Optional configuration for physics-based animations
});
return (
<animated.div style={props} className="box">
Hello, I'm an animated box!
</animated.div>
);
};
export default Box;
Explanation:
useSpring
: This hook creates an animation for the element. Thefrom
object specifies the initial values of the animated properties, and theto
object specifies the final values.animated.div
:animated
is a higher-order component from React Spring that you can use to animate HTML elements likediv
,span
,button
, etc.config
: This allows you to customize the physics of the animation.tension
controls how fast the animation moves, andfriction
controls the resistance.
3. Animating Multiple Properties
You can animate multiple properties at once, like opacity, scale, and position.
Example: Multiple Animations
const AnimatedBox = () => {
const props = useSpring({
from: { opacity: 0, transform: 'translateY(-100px)' },
to: { opacity: 1, transform: 'translateY(0)' },
config: { tension: 180, friction: 12 },
});
return (
<animated.div style={props} className="animated-box">
I slide in from above!
</animated.div>
);
};
In this example:
- The box starts with an opacity of 0 and is translated 100px above its final position (
translateY(-100px)
). - As the animation runs, the opacity increases and the box slides down to its final position.
4. Animating on Scroll
React Spring is great for scroll-based animations. You can use the useSpring
hook in combination with a scroll event to trigger animations as the user scrolls.
Example: Fade-In on Scroll
import { useEffect, useState } from 'react';
import { useSpring, animated } from '@react-spring/web';
const ScrollFadeIn = () => {
const [isInView, setIsInView] = useState(false);
useEffect(() => {
const handleScroll = () => {
const position = window.scrollY;
if (position > 200) setIsInView(true); // Trigger animation after scrolling 200px
};
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, []);
const fadeProps = useSpring({
opacity: isInView ? 1 : 0,
transform: isInView ? 'translateY(0)' : 'translateY(50px)',
config: { tension: 170, friction: 26 },
});
return (
<animated.div style={fadeProps} className="scroll-fade">
Scroll down to see me fade in!
</animated.div>
);
};
In this example:
- A scroll event listener is added to detect when the user scrolls past a certain point (200px in this case).
- When the condition is met, the element fades in with a
translateY
animation.
5. Using useTrail
for Staggered Animations
React Spring also provides hooks like useTrail
that help animate a list of elements with a staggered effect.
Example: Staggering List Items
import { useTrail, animated } from '@react-spring/web';
const StaggeredList = () => {
const items = ['Item 1', 'Item 2', 'Item 3', 'Item 4'];
// Stagger animation for list items
const trail = useTrail(items.length, {
opacity: 1,
transform: 'translateX(0)',
from: { opacity: 0, transform: 'translateX(-100px)' },
config: { mass: 1, tension: 200, friction: 30 },
});
return (
<div>
{trail.map((style, index) => (
<animated.div key={index} style={style} className="list-item">
{items[index]}
</animated.div>
))}
</div>
);
};
In this example:
useTrail
: This hook allows you to animate a collection of elements with a staggered delay, creating a nice sequential animation effect.trail.map
: Thetrail
array holds the styles for each animated item. You use.map()
to apply each style to the corresponding element.
6. Animating on Hover
React Spring can also handle hover effects, making elements animate smoothly when the user hovers over them.
Example: Hover Effect
const HoverBox = () => {
const [props, set] = useSpring(() => ({ scale: 1 }));
return (
<animated.div
style={{ transform: props.scale.to((s) => `scale(${s})`) }}
onMouseEnter={() => set({ scale: 1.2 })}
onMouseLeave={() => set({ scale: 1 })}
className="hover-box"
>
Hover over me to scale up!
</animated.div>
);
};
In this example:
- When the user hovers over the box, its scale increases to
1.2
. When the hover ends, it scales back to its original size. onMouseEnter
andonMouseLeave
are used to trigger the hover animation.
7. Animating Modals with React Spring
You can also use React Spring to animate modals, making them smoothly fade in and out when opened and closed.
Example: Animated Modal
const Modal = ({ isOpen, onClose }) => {
const modalProps = useSpring({
opacity: isOpen ? 1 : 0,
transform: isOpen ? 'scale(1)' : 'scale(0.8)',
config: { tension: 170, friction: 12 },
});
return (
<animated.div style={modalProps} className="modal-overlay" onClick={onClose}>
<div className="modal-content" onClick={(e) => e.stopPropagation()}>
<h2>Modal Content</h2>
<button onClick={onClose}>Close</button>
</div>
</animated.div>
);
};
In this example:
- The modal fades in (
opacity: 1
) and scales up when it’s open (scale(1)
), and fades out and scales down when it’s closed (opacity: 0
andscale(0.8)
).