InterviewHubPRO
Section Overview
Q385

Question 385 of 445

Part 11: Legacy Architecture, Migration Patterns & Historical Internals (354 - 445)

87%
React & Modern Frontend (445 Qs)•Part 11: Legacy Architecture, Migration Patterns & Historical Internals (354 - 445)

Why we need to pass a function to setState()?

The reason behind for this is that setState() is an asynchronous operation. React batches state changes for performance reasons, so the state may not change immediately after setState() is called. That means you should not rely on the current state when calling setState() since you can't be sure what that state will be. The solution is to pass a function to setState(), with the previous state as an argument. By doing this you can avoid issues with the user getting the old state value on access due to the asynchronous nature of setState().

vbnet
Let's say the initial count value is zero. After three consecutive increment operations, the value is going to be incremented only by one.
javascript
    // assuming this.state.count === 0
    this.setState({ count: this.state.count + 1 });
    this.setState({ count: this.state.count + 1 });
    this.setState({ count: this.state.count + 1 });
    // this.state.count === 1, not 3
css
If we pass a function to `setState()`, the count gets incremented correctly.
javascript
    this.setState((prevState, props) => ({
      count: prevState.count + props.increment,
    }));
    // this.state.count === 3 as expected
markdown
**(OR)**

Why function is preferred over object for setState()?

vbnet
React may batch multiple `setState()` calls into a single update for performance. Because `this.props` and `this.state` may be updated asynchronously, you should not rely on their values for calculating the next state.

This counter example will fail to update as expected:
javascript
    // Wrong
    this.setState({
      counter: this.state.counter + this.props.increment,
    });
vbnet
The preferred approach is to call `setState()` with function rather than object. That function will receive the previous state as the first argument, and the props at the time the update is applied as the second argument.
javascript
    // Correct
    this.setState((prevState, props) => ({
      counter: prevState.counter + props.increment,
    }));