Building an Progress Bar Component in React
Here is a complete breakdown and explanation of how you built the animated Progress Bar in React, including how it works, animations, and styling — all step-by-step.
✅ Objective
You built a smooth animated progress bar that visually represents a percentage using:
- React state and effect (useState, useEffect)
- CSS transitions
- Transform-based animation for smooth rendering
✅ 1. Component & Props
export default function ProgressBar({ progress }) { const [value, setValue] = useState(0); ... }
✅ What is happening here:
- The component receives a progress prop (a number between 0 and 100).
- Internally, you use value state to animate from old to new progress.
✅ 2. Animating with useEffect
useEffect(() => { setTimeout(() => setValue(progress), 100); }, [progress]);
✅ Explanation:
- When progress changes, you use a delayed state update (setTimeout).
- This enables the CSS transition to animate smoothly from old to new value.
- You could also use requestAnimationFrame or a transition library, but setTimeout with CSS transitions works great for simple cases.
✅ 3. Rendering the Progress Bar
<div className="box"> <div className="bar" style={{ transform: `translateX(${value - 100}%)` }}> {progress}% </div> </div>
✅ What is going on:
- The .bar is animated by shifting its position using transform: translateX(...).
- When value is 0 → translateX(-100%) (hidden)
- When value is 100 → translateX(0%) (fully visible)
- Intermediate values animate smoothly between these states.
✅ 4. Styling the Progress Bar
.App { font-family: sans-serif; text-align: center; } .box { border: 2px solid black; border-radius: 10px; overflow: hidden; } .bar { background-color: green; color: white; text-align: end; padding: 2px; transition: 0.5s ease-in; }
✅ Key Points:
- .box: Acts as a container with rounded borders and hidden overflow to clip .bar.
- .bar: The animated fill. Uses transition for smoothness and transform for movement.
✅ 5. Complete Component Code Recap
✅ ProgressBar.js
import { useEffect, useState } from "react"; export default function ProgressBar({ progress }) { const [value, setValue] = useState(0); useEffect(() => { setTimeout(() => setValue(progress), 100); }, [progress]); return ( <div className="box"> <div className="bar" style={{ transform: `translateX(${value - 100}%)` }}> {progress}% </div> </div> ); }
✅ styles.css
.App { font-family: sans-serif; text-align: center; } .box { border: 2px solid black; border-radius: 10px; overflow: hidden; } .bar { background-color: green; color: white; text-align: end; padding: 2px; transition: 0.5s ease-in; }
✅ 6. Example Usage
import { useState } from "react"; import ProgressBar from "./ProgressBar"; export default function App() { const [progress, setProgress] = useState(0); return ( <div className="App"> <h1>Animated Progress Bar</h1> <button onClick={() => setProgress((p) => (p + 10) % 110)}>Increase</button> <ProgressBar progress={progress} /> </div> ); }