If you do an asynchronous action that updates the state in componentWillMount
(like the docs say), but the component is unmounted (the user navigates away) before that async call is complete, you end up with the async callback trying to set the state on a now unmounted component, and an
"Invariant Violation: replaceState(...): Can only update a mounted or mounting component."
error.
What's the best way around this?
Thanks.
To update the state of a component, you use the setState method. However it is easy to forget that the setState method is asynchronous, causing tricky to debug issues in your code. The setState function also does not return a Promise. Using async/await or anything similar will not work.
setState is asynchronous for this reason, and React will batch setState calls inside of React based event handlers to reduce component re-renders.
State can be updated in response to event handlers, server responses, or prop changes. This is done using the setState() method. The setState() method enqueues all of the updates made to the component state and instructs React to re-render the component and its children with the updated state.
TL;DR: useState is an asynchronous hook and it doesn't change the state immediately, it has to wait for the component to re-render. useRef is a synchronous hook that updates the state immediately and persists its value through the component's lifecycle, but it doesn't trigger a re-render.
You can use component.isMounted
method to check if component was actually attached to the DOM before replacing its state. Docs.
isMounted()
returnstrue
if the component is rendered into the DOM,false
otherwise. You can use this method to guard asynchronous calls tosetState()
orforceUpdate()
.
UPD: Before you downvote. This answer was given 2 freaking years ago. And it was the way to do stuff back that days. If you are just starting to use React do not follow this answer. Use componentDidMount
or whatever another lifecycle hook you need.
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