I’m building a loading bar in React, but something is not right. I want it to fill width 100%
once the timer is reached 3 seconds, but for some reason it does not work as expected.
const { useState, useEffect } = React;
const Loading = () => {
const [isLoading, setIsLoading] = useState(true);
const [progress, setProgress] = useState(0);
useEffect(() => {
const duration = 3000;
const increment = 100 / duration;
const timer = setInterval(() => {
setProgress((prevProgress) => {
const newProgress = prevProgress + increment;
if (newProgress >= 100) {
clearInterval(timer);
setIsLoading(false);
return 100;
}
return newProgress;
});
}, 10);
return () => clearInterval(timer);
}, []);
return (
<div className="canvas">
{isLoading && (
<div
className="loadng_bar"
style={{ width: `${progress}%` }}
></div>
)}
</div>
);
};
// Render it
ReactDOM.createRoot(
document.getElementById("root")
).render(
<Loading />
);
.loadng_bar {
position: absolute;
top: 0;
left: 0;
width: 0;
height: 5px;
background-color: #c4483f;
transition: width 3.05s linear;
}
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.development.js"></script>
It should increase the progress
up to full width during 3 seconds. How can I achieve it?
2
Answers
It looks like the issue with your loading bar stems from how you’re calculating the
increment
value and the timing of thesetInterval
. The goal is to fill the loading bar over a period of 3 seconds, but the way you’re currently doing it may not align with that expectation.Here’s a revised version of your code that should work as intended:
CSS
Make sure your CSS is correctly defined as well:
Key Changes Explained
Increment Calculation: The
increment
is now calculated based on how many times the interval runs in the total duration. Since you’re updating every 10 milliseconds, you divide the total duration by the interval time to get the correct number of increments.CSS Class Name: Ensure that your CSS class name matches what you use in your React component (
loading_bar
instead ofloadng_bar
).With these adjustments, your loading bar should now fill to 100% over a period of exactly 3 seconds.
Option 1: Animate with CSS only
You can remove the
setInterval
and handle the animation with pure CSS by setting the width to 100% initially and letting CSS handle the timing:Option 2: Animate with JavaScript
If you prefer to control the animation manually with JavaScript using
setInterval
, you don’t need the CSS transition property. Here’s the corrected approach: