So I have some confusion regarding the async nature of setState in ReactJS. As per React docs, you shouldn't use this.state inside setState(). But if I have a counter as a state and i want to update it on click like this:
class App extends React.Component {
state = { counter: 0 }
onClick = () => {
this.setState({counter: this.state.counter + 1})
}
render() {
return (
<div>
<div>{this.state.counter}</div>
<p onClick={this.onClick}>Click me</p>
</div>
)
}
}
This works as expected. So why is this code wrong?
UPDATE: I know that setState is async, and it accepts a callback which has previous state as an argument, but I am not sure why I should use it here? I want to refer to the old state inside setState, so why should I use the callback function in this case? Whenever this.setState()
is executed, this.state
inside it will always refer to the old state, and its value will be changed to the new state only after setState has finished executing, not while it is executing.
setState() is executed, this. state inside it will always refer to the old state, and its value will be changed to the new state only after setState has finished executing, not while it is executing.
The setState() Method 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.
setState() setState(updater[, callback]) setState() enqueues changes to the component state and tells React that this component and its children need to be re-rendered with the updated state. This is the primary method you use to update the user interface in response to event handlers and server responses.
setState" causes React to re-render your application and update the DOM. you can also track of prevstate in setState If you use setState in constructor you would get error like this:Can only update a mounted or mounting component. This usually means you called setState() on an unmounted component.
You have access to prevState
from within your setState call:
this.setState((prevState) => ({
counter: prevState.counter +1
}))
That will allow you to safely increment the current state value.
The React documentation summarises why you cannot rely on this.state
to be accurate during update: https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous
setState
accepts a function as a parameter with previous state as argument.
Refacto as follows to avoid competition problems:
onClick = () => {
this.setState(prevState => ({counter: prevState.counter + 1}))
}
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