ReactJS - Animations
ReactJS - Animations
Section titled “ReactJS - Animations”Animations can significantly enhance user experience by making UI transitions smoother and more intuitive. React itself doesn’t have a built-in animation system, but it provides hooks for, and integrates well with, third-party animation libraries. One popular choice for managing CSS transitions and animations is react-transition-group.
This chapter will demonstrate how to create basic animations using react-transition-group.
Step 1 - Install react-transition-group
Section titled “Step 1 - Install react-transition-group”react-transition-group is a library that exposes components for managing the stages of transitions, making it easier to implement animations when components enter or leave the DOM.
Install it using npm or yarn:
your-project-directory> npm install react-transition-groupyour-project-directory> yarn add react-transition-groupStep 2 - Add CSS File
Section titled “Step 2 - Add CSS File”Animations with react-transition-group rely on CSS transitions or animations. Create a CSS file (e.g., animations.css in your src folder) and import it into your component or main application file.
Example: src/animations.css (we’ll populate this later)
And import it in App.js or main.js:
import './animations.css'; // Adjust path as necessaryStep 3 - Appear Animation (CSSTransition)
Section titled “Step 3 - Appear Animation (CSSTransition)”The CSSTransition component from react-transition-group helps animate a single component when it first mounts or when its in prop changes.
Let’s create a component that fades in on appear.
src/App.jsx
Section titled “src/App.jsx”import React, { useState, useEffect } from 'react';import { CSSTransition } from 'react-transition-group';import './animations.css'; // Make sure to create and import this CSS file
function App() { const [showTitle, setShowTitle] = useState(false);
// Trigger the animation after the component mounts useEffect(() => { setShowTitle(true); }, []);
return ( <div> <CSSTransition in={showTitle} // Controls the transition (true to enter, false to exit) timeout={500} // Duration of the transition in milliseconds classNames="fade" // Prefix for CSS classes (e.g., fade-enter, fade-enter-active) appear // Enable appear transition on initial mount unmountOnExit // Optional: remove the component from DOM when exited > <h1>My Animated Element</h1> </CSSTransition> </div> );}
export default App;src/main.js (or src/index.js)
Section titled “src/main.js (or src/index.js)”import React from 'react';import ReactDOM from 'react-dom/client';import App from './App.jsx';
const root = ReactDOM.createRoot(document.getElementById('root'));root.render( <React.StrictMode> <App /> </React.StrictMode>);src/animations.css (for Appear animation)
Section titled “src/animations.css (for Appear animation)”/* Fade Appear Animation */.fade-appear { opacity: 0;}.fade-appear-active { opacity: 1; transition: opacity 500ms ease-in;}
/* If you also want enter/exit animations for dynamic show/hide later */.fade-enter { opacity: 0;}.fade-enter-active { opacity: 1; transition: opacity 500ms ease-in;}.fade-exit { opacity: 1;}.fade-exit-active { opacity: 0; transition: opacity 500ms ease-in;}Explanation:
-
We use
useStateanduseEffectto setshowTitletotrueafter the component mounts, triggering theinprop ofCSSTransition. -
CSSTransitionprops:in: Boolean. Whentrue, it applies enter/appear classes. Whenfalse, it applies exit classes.timeout: Duration of the animation. It should match your CSS transition duration.classNames: A string prefix.react-transition-groupwill append suffixes like-appear,-appear-active,-enter,-enter-active,-exit,-exit-active.appear: Enables the initial mount animation using*-appearand*-appear-activeclasses.unmountOnExit: If true, the component will be removed from the DOM after it finishes exiting.
When the app loads, the <h1> element will fade in.
Step 4 - Enter and Leave Animations (TransitionGroup)
Section titled “Step 4 - Enter and Leave Animations (TransitionGroup)”To animate a list of items (e.g., when adding or removing them), use the TransitionGroup component in conjunction with CSSTransition.
src/App.jsx (for List Animation)
Section titled “src/App.jsx (for List Animation)”import React, { useState } from 'react';import { CSSTransition, TransitionGroup } from 'react-transition-group';import './animations.css'; // Ensure this CSS file includes .item-* classesimport { v4 as uuidv4 } from 'uuid'; // For unique keys: npm install uuid
function App() { const [items, setItems] = useState([ { id: uuidv4(), text: 'Item 1...' }, { id: uuidv4(), text: 'Item 2...' }, ]);
const handleAddItem = () => { const newItemText = prompt('Enter new item text:'); if (newItemText) { setItems(prevItems => [ ...prevItems, { id: uuidv4(), text: newItemText }, ]); } };
const handleRemoveItem = (idToRemove) => { setItems(prevItems => prevItems.filter(item => item.id !== idToRemove)); };
return ( <div> <button onClick={handleAddItem}>Add Item</button> <TransitionGroup component="ul"> {/* component prop defines the wrapping element */} {items.map(({ id, text }) => ( <CSSTransition key={id} // Crucial: unique key for each item timeout={500} classNames="item" > <li onClick={() => handleRemoveItem(id)}> {text} </li> </CSSTransition> ))} </TransitionGroup> </div> );}
export default App;src/animations.css (additions for List Animation)
Section titled “src/animations.css (additions for List Animation)”/* ... (keep .fade-* classes from above if needed) ... */
/* Item Enter/Exit Animation */.item-enter { opacity: 0; transform: translateX(-100px);}.item-enter-active { opacity: 1; transform: translateX(0); transition: opacity 500ms ease-in, transform 500ms ease-in;}.item-exit { opacity: 1; transform: translateX(0);}.item-exit-active { opacity: 0; transform: translateX(100px); transition: opacity 500ms ease-in, transform 500ms ease-in;}Explanation for List Animation:
-
We use
uuidto generate unique IDs for list items, which is essential forTransitionGroupto track items correctly. Install it vianpm install uuid. -
TransitionGroup: Wraps multipleCSSTransitioncomponents. It monitors its children. When a child is added or removed,TransitionGroupmanages its animation state. -
CSSTransition(insidemap): Each list item is wrapped in its ownCSSTransition.- The
keyprop MUST be unique and stable for each item. classNamesis set to"item", so CSS classes likeitem-enter,item-enter-active, etc., will be applied.
- The
-
handleAddandhandleRemove: These functions update theitemsstate. React re-renders, andTransitionGroupdetects changes in its children, triggering animations.
When you add an item, it will animate in (slide from left and fade in). When you click an item to remove it, it will animate out (slide to right and fade out).
Note on prompt(): Using prompt() is simple for demos but generally not recommended for production UIs due to its blocking nature and browser-inconsistent styling. In real apps, you’d use a proper input field within your React component.
Further Exploration:
react-transition-group also offers Transition and SwitchTransition components for more granular control. For more complex physics-based animations or interactions, libraries like Framer Motion (https://www.framer.com/motion/) or React Spring (https://www.react-spring.dev/) are excellent choices. Always refer to the official documentation of these libraries for the most up-to-date information and advanced features.