Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

this.state inside setState ReactJS

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.

like image 363
darKnight Avatar asked Aug 13 '18 08:08

darKnight


People also ask

Can we use this state inside setState?

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.

How do I get a state on setState?

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.

What is this setState in React?

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.

Can we use setState again inside this setState () and if it does then what will happen?

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.


2 Answers

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

like image 161
Steve Vaughan Avatar answered Oct 06 '22 00:10

Steve Vaughan


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}))
}
like image 42
Alexandre Annic Avatar answered Oct 06 '22 00:10

Alexandre Annic