Animations in React with react-spring

Published on 11.8.2019

Animations can make your web applications feel more dynamic and interactive, and React, being a powerful library for UI development, offers great ways to add animations. One of the best libraries for handling animations in React is react-spring. It’s a flexible and easy-to-use animation library that works well with React’s declarative nature.

In this post, we’ll walk through how to add smooth animations in React using react-spring, especially in functional components using Hooks. We’ll go through examples like fade-in effects and animated modals that can enhance the user experience of your React apps.

Let’s dive into it!


What is react-spring?

react-spring is a spring-physics-based animation library for React. Unlike traditional keyframe-based CSS animations, react-spring provides an interpolation between states, making the animation more natural and fluid. It uses a spring model (hence the name) to simulate real-world physics, resulting in more organic and smooth transitions.

You can use react-spring to animate various properties of a component, such as opacity, scale, position, and more. The animations are driven by the React state, which means they’re fully integrated into your app’s lifecycle.


Installing react-spring

To get started, we first need to install react-spring:

npm install react-spring

Once the library is installed, you’re ready to start adding animations!


Example 1: Fade-In Effect Using react-spring

One of the most common animations is the fade-in effect. In this example, we’ll animate the opacity of an element, making it smoothly fade into view when the component mounts.

App.js

import React, { useState } from 'react';
import { useSpring, animated } from 'react-spring';

const App = () => {
  const [isVisible, setIsVisible] = useState(false);

  // Using react-spring's useSpring hook to create a fade-in effect
  const fadeIn = useSpring({
    opacity: isVisible ? 1 : 0, // Fade in when true, fade out when false
    transform: isVisible ? 'translateY(0)' : 'translateY(20px)', // Slight bounce effect when fading in
    config: { tension: 200, friction: 20 } // Spring configuration for smoothness
  });

  return (
    <div>
      <button onClick={() => setIsVisible(!isVisible)}>
        Toggle Fade In
      </button>
      
      <animated.div style={fadeIn}>
        <h1>This is a fade-in effect!</h1>
      </animated.div>
    </div>
  );
};

export default App;

Explanation:

  1. useSpring Hook: The useSpring hook is used to define the animation. We set the opacity to either 1 (fully visible) or 0 (invisible) based on the isVisible state.
  2. animated.divanimated is a higher-order component from react-spring that wraps a regular HTML element (in this case, a div). It makes the element animatable.
  3. Spring Configurations: We can adjust the tension and friction of the spring to control the speed and feel of the animation. These values create a smooth fade with a slight bounce effect.

Example 2: Animated Modal Using react-spring

Next, let’s take the fade-in concept and build a modal that smoothly appears and disappears using react-spring. We’ll use the same useSpring hook to animate the modal’s opacity and position.

Modal.js

import React from 'react';
import { useSpring, animated } from 'react-spring';
import './Modal.css';

const Modal = ({ isOpen, onClose }) => {
  const modalAnimation = useSpring({
    opacity: isOpen ? 1 : 0,
    transform: isOpen ? 'translateY(0)' : 'translateY(-50px)',
    config: { tension: 170, friction: 26 },
  });

  return (
    isOpen && (
      <div className="modal-overlay">
        <animated.div style={modalAnimation} className="modal-content">
          <button onClick={onClose} className="close-button">X</button>
          <h2>Welcome to the Animated Modal!</h2>
          <p>Click the button to close this modal.</p>
        </animated.div>
      </div>
    )
  );
};

export default Modal;

App.js

import React, { useState } from 'react';
import Modal from './Modal';

const App = () => {
  const [isModalOpen, setIsModalOpen] = useState(false);

  const openModal = () => setIsModalOpen(true);
  const closeModal = () => setIsModalOpen(false);

  return (
    <div className="App">
      <button onClick={openModal}>Open Modal</button>
      <Modal isOpen={isModalOpen} onClose={closeModal} />
    </div>
  );
};

export default App;

Modal.css

.modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 1000;
}

.modal-content {
  background-color: white;
  padding: 20px;
  border-radius: 5px;
  width: 300px;
  text-align: center;
}

.close-button {
  background: #f44336;
  color: white;
  border: none;
  border-radius: 50%;
  width: 30px;
  height: 30px;
  font-size: 18px;
  position: absolute;
  top: 10px;
  right: 10px;
  cursor: pointer;
}

Explanation:

  1. Animated Modal: When the isOpen state is true, the modal becomes visible with an animated fade-in effect. It also translates from a translateY(-50px) position to translateY(0) to make it appear to slide up.
  2. Spring Configurations: We’ve tweaked the tension and friction values to make the modal animation feel smooth and natural.
  3. Conditional Rendering: The modal only renders when isOpen is true to prevent unnecessary rendering.

Example 3: Multiple Animations with react-spring

You can animate multiple properties at once. Here’s an example where we animate both the position and scale of a button on hover using useSpring.

App.js

import React from 'react';
import { useSpring, animated } from 'react-spring';

const App = () => {
  const springProps = useSpring({
    transform: 'scale(1.1)',
    opacity: 1,
    from: { opacity: 0, transform: 'scale(1)' },
    reset: true,
    reverse: true,
    config: { tension: 170, friction: 26 }
  });

  return (
    <div>
      <animated.button style={springProps}>
        Hover over me!
      </animated.button>
    </div>
  );
};

export default App;

Explanation:

  • Scaling and Fading: The button will scale up when hovered over and fade into view using both transform and opacity.
  • reset and reverse: These props allow the animation to reset to its initial state when the hover effect is no longer active, ensuring smooth transitions.

Conclusion

React-spring is an amazing tool to make your React applications more engaging with smooth and fluid animations. In this tutorial, we explored how to:

  • Use fade-in effects with the useSpring hook.
  • Build a modal with an animated entrance and exit.
  • Animate multiple properties like scale and opacity simultaneously.

Animations are a great way to improve the user experience, and with react-spring, it’s easy to add dynamic transitions without worrying about the complexities of keyframes or CSS animations.

Give it a try in your own projects, and happy animating!

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *