Why doesn't calling the setState method result in an immediate state change?

Well, I will try to do it quickly, because SHOULD be an easy solution ...

I read a bunch of similar questions, and the answer seems quite obvious. Nothing I'd ever need to look for in the first place! But ... I have a mistake that I cannot understand how to fix or why this is happening.

Properly:

class NightlifeTypes extends Component { constructor(props) { super(props); this.state = { barClubLounge: false, seeTheTown: true, eventsEntertainment: true, familyFriendlyOnly: false } this.handleOnChange = this.handleOnChange.bind(this); } handleOnChange = (event) => { if(event.target.className == "barClubLounge") { this.setState({barClubLounge: event.target.checked}); console.log(event.target.checked) console.log(this.state.barClubLounge) } } render() { return ( <input className="barClubLounge" type='checkbox' onChange={this.handleOnChange} checked={this.state.barClubLounge}/> ) } 

More code surrounds this, but this is my problem. Should work, huh?

I also tried this:

 handleOnChange = (event) => { if(event.target.className == "barClubLounge") { this.setState({barClubLounge: !this.state.barClubLounge}); console.log(event.target.checked) console.log(this.state.barClubLounge) } 

So, I have those two console.log() , both should be the same. I literally set the state just like event.target.checked in the line above it!

But he always returns the opposite of what he needs.

The same thing happens when I use !this.state.barClubLounge ; If it starts with false, my first click remains false, even if the checkbox is checked or not based on state !!

This is a crazy paradox, and I have no idea what is going on, please help!

+11
source share
2 answers

The reason setState is asynchronous , you cannot expect an updated state value immediately after setState , if you want to check the value, use the callback method. Pass the method as a callback that will be executed after the setState completes its task.

Why is setState asynchronous?

This is because setState modifies state and causes re-rendering. This can be a costly operation and making it synchronous can leave the browser unresponsive. Therefore, calls to setState asynchronous , as well as a package for better experience and interface performance.

From the Doc :

setState () does not immediately mutate this.state, but creates a pending state transition. Accessing this.state after calling this method can potentially return an existing value. There is no guarantee that synchronized operation of setState calls and calls can be collected to improve performance.

Using the callback method with setState:

To check the updated state value immediately after setState , use the callback method, for example:

 setState({ key: value }, () => { console.log('updated state value', this.state.key) }) 

Check it:

 class NightlifeTypes extends React.Component { constructor(props) { super(props); this.state = { barClubLounge: false, seeTheTown: true, eventsEntertainment: true, familyFriendlyOnly: false } this.handleOnChange = this.handleOnChange.bind(this); } handleOnChange = (event) => { let value = event.target.checked; if(event.target.className == "barClubLounge") { this.setState({ barClubLounge: value}, () => { //here console.log(value); console.log(this.state.barClubLounge); //both will print same value }); } } render() { return ( <input className="barClubLounge" type='checkbox' onChange={this.handleOnChange} checked={this.state.barClubLounge}/> ) } } ReactDOM.render(<NightlifeTypes/>, document.getElementById('app')) 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> <div id='app'/> 
+22
source

This is a design for performance reasons. setState in React is a feature guaranteed to re-render a component, which is an expensive CPU process. Thus, its designers wanted to optimize by collecting several rendering actions into one, therefore, setState is asynchronous.

0
source

Source: https://habr.com/ru/post/1015146/


All Articles