There are quite a few similar questions, but I haven't found a clear answer.
Sometimes, I need to run CSS animation in React again, after it's complete, under certain condition. There's usually quite complex logic behind this case, so I simplified it to show what I mean without extra complexity.
Let's say I'm having a checkbox to decide whether I want the animation to run or not:
When checkbox is disabled, the animation stops, but it finishes its cycle if it's already going. I was wondering what is the proper way to re-run the animation (i.e. remove the class and add it again) with React. Here's my component:
import { useState, useEffect } from 'react';
export default function Spinner() {
const [isSpinning, setIsSpinning] = useState(true);
const [isChecked, setIsChecked] = useState(true);
useEffect(
() => {
if (isChecked) {
setIsSpinning(true);
}
},
[isChecked]
);
const spin = () => {
setIsSpinning(false);
if (isChecked) {
// without setTimeout() it doesn't work
window.setTimeout(() => setIsSpinning(true));
}
};
return (
<div className="container">
<input
type="checkbox"
checked={isChecked}
onChange={toggleCheckbox}
/>
<div
className={isSpinning && 'spinning'}
onAnimationEnd={endSpin}
>
Hello!
</div>
</div>
);
};
And the CSS:
@keyframes spinning {
from {
transform: rotateX(0);
}
to {
transform: rotateX(360deg);
}
}
.container {
display: flex;
gap: .5em;
}
.spinning {
animation: spinning 1s;
}
I'm using window.setTimeout(fn) to add class name again after it's removed. Otherwise, it happens in the same render cycle and it behaves like the class was always there, so animation never re-runs. It works, but isn't there another, less hacky way to add class in next render cycle in React?
