I am creating a component with an animation that occurs with a css class toggle. Sandbox of the example here.
The css class is applied conditionaly against the transitioned
field, so we should get an animation when the transtioned
field goes form false
to true
.
Problem:
The animation doesn't happen in the case where the state if modified like this :
animateWithoutST = () => {
this.setState({transitioned: false},
() => this.setState({transitioned: true}))
}
But it works if it the second setState
is called within a setTimeout
callback like this:
animateWithST = () => {
this.setState({ transitioned: false },
() => {
setTimeout(() => this.setState({ transitioned: true }))
}
)
}
Why isn't animateWithoutST
working as expected although my component is rendering in the right order ?
This looked definitely bizarre and I had to dig into it until I understood what is happening.
So, yeah without the setTimeout
it doesn't work, not even in the componentDidUpdate
method and there is an explanation: you are changing the state, and it is updated, and render is called twice BUT because of browser optimization we don't see the animation happening: "browsers are not re-rendering stuff that changed in the same animation frame".
When you use the setTimeout
you are forcing the 2nd state update to go into the next animation frame and voila you see the animation. Even with the current timeout value set to 0, it might not work on some browsers, but if you set the value to > 16ms aprox, it prob will work always (you need a value greater than an animation frame).
You can also use requestAnimationFrame
, twice to assure your both state updates fall into different animation frames, check it here.
I found all this info in this article, check it because it is extremely well explained. Does now make sense to you?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With