Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does using function inside React's #setState solve async issues?

From the docs, it says "React may batch multiple setState() calls into a single update for performance" so it recommends using a function instead of an object for setState's argument. How does this solve the problem?

// Wrong
this.setState({
  counter: this.state.counter + this.props.increment,
});

// Correct
this.setState((prevState, props) => ({
  counter: prevState.counter + props.increment
}));
like image 750
stackjlei Avatar asked Nov 08 '16 21:11

stackjlei


People also ask

How do I use the function inside a function in React?

If this function need an access to any component properties or method then you should place it inside the component or If this is only utility function then place it inside helper library separate from component.

Why do we use arrow functions in React?

In short, with arrow functions there is no binding of this . In regular functions the this keyword represented the object that called the function, which could be the window, the document, a button or whatever. With arrow functions, the this keyword always represents the object that defined the arrow function.

How do you call a function inside a component React?

To call a child's function from a parent component in React: Wrap the Child component in a forwardRef . Use the useImperativeHandle hook in the child to add a function to the Child . Call the Child's function from the Parent using the ref, e.g. childRef.

How do you call a function automatically in React?

In React, the onClick handler allows you to call a function and perform an action when an element is clicked. onClick is the cornerstone of any React app. Click on any of the examples below to see code snippets and common uses: Call a Function After Clicking a Button.


1 Answers

When you pass in an object to setState, react will take whatever you pass in, create an event that will track what was passed in, and then will eventually update state. As the docs say, if multiple setStates are run, react may batch those together and since its going to happen asynchronously, aka at some point down the road, when you run the first example it may use a this.state.counter that is actually old and cause unexpected side effects.

The second option is considered more safe because it is much like a promise: When you pass in a function, React will only run this function once the state has actually been updated. This ensures that you have correct this.state.counter variable each time you update by using the prevState variable they provide as an argument to the callback.

I haven't myself ran into an issue using the first method but I also haven't tried flooding a bunch of setStates calls at once which I'm sure is when this does come up. The main way I've seen this foul people up is when they are trying to use the new state right after setting state.

for example:

increaseCounter() {
 this.setState({
   counter: this.state.counter + this.props.increment,
 });

 // this will more then likely be the previous value 
 // as setState does not run right away, but asynchronously 
 this.useNewCounter(this.state.counter) 
}

in that example one might expect that when useNewCounter is called that it would be using the latest state, but it will not, the reference will still be pointed at the previous value until react updates the state which will be at some point after this method is called.

like image 79
finalfreq Avatar answered Oct 25 '22 16:10

finalfreq