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>
);
}