I made a very simple animated counter using effect hooks and a setTimeout. It works fine so far except for the speed.
If there are multiple counters on the same page, I would like that they all finish their animation at the same time regardless of the final count. I though that using the calculation speed / count on the timeout would work but it just seems random.
const Counter = ({ count, speed }) => {
const timeout = useRef();
const [counter, setCounter] = useState(0);
useEffect(() => {
if(counter > 0) {
setCounter(0);
timeout.current = null;
}
}, [count]);
useLayoutEffect(() => {
if(counter < count) {
timeout.current = setTimeout(() => {
setCounter(prev => prev + 1)
}, speed / count);
}
return () => {
if(timeout.current) clearTimeout(timeout.current);
}
});
return (
<div id="counter">
{Intl.NumberFormat('en-EN').format(counter)}
</div>
);
}
I think it's because of the re-render times that can't be predicted, but I'm not sure. Here is a CodePen with controls.
How can I control the speed of the counter?