May 19, 2024

React.js – Why setState

Let’s now look at a few examples on the benefits of setState. To do that, we would use a counter component to illustrate this. Before we proceed, I would you to use a tool that make coding easy.

  1. The ES7 React…JS Snippets Extension
  2. The Counter Example
  3. Async Call to setState
  4. Calculate State Based on Previous State
  5. Summary on setState()

 

1. The ES7 React…JS Snippets Extension

This tools is an extension of VS Code and it helps generate common codes by inserting code snippet.

  • To install it, click on the Extensions icon on the left of the window
  • Search for VS Code ES7 React/Redux/React-Native/JS snippets
  • Then click on install. Then you have it!
VS Code ES7 React/Redux/React-Native/JS snippets
VS Code ES7 React/Redux/React-Native/JS snippets

In a blank file

  • type rce and tab out to create class component
  • type rfc and tab out to create functional component
  • type rconst and tab out to create constructor
  • I will be telling you more as we go….

 

2. The Counter Example

Let’s create a component named Counter. This component would have a state called count. It would also have a button. The button is displayed below the count value on the page.

So when the user clicks on the button, the count value will increase.

Changing State Explicitly

In the code below, the count value is increased by 1. We would also display the current count value in the console using console.log().

import React, { Component } from 'react'

class Counter extends Component {
    constructor(props) {
        super(props)   
        this.state = {
             count: 0
        }
    }
    
    //we are directly changing the state
    //without using the setState() method
    incrementCount(){
        this.state.count = this.state.count + 1
        console.log(this.state.count)
    }

    render() {
        return (
            <div>
                Current Count: {this.state.count} <br />
                <button onClick={() => this.incrementCount()}>
                    Increment
                </button>
            </div>
        )
    }
}

export default Counter

Run this code and keep the console window open. When you click on the button, the value in the console increments, but the value in the UI remains unchanged. So you see that if you set the state directly, the UI is not re-rendered.

So, alter the code to use the setState() method. The modified function is shown below:

    //Using the setState() method
    incrementCount(){
        this.setState({
            count: this.state.count + 1
        })
        console.log(this.state.count)
    }

Now everything works fine!. The count changes in the UI when you click the button.

 

3. Async Call to setState()

You’ll observe that in the previous example, the value in the console is always 1 less than the value in the UI. This is because calls to setState() are asynchronous. This means that the operation is performed only when the function returns. Therefore the code following it (console.log statement) may execute beforeĀ  the state is actually set.

So if we want to execute a code after the state is set, we need to pass a callback function as a second parameter to the setState() method. The modified incrementCount() function is shown below:

    //Using the setState() method
    incrementCount(){
        this.setState({
            count: this.state.count + 1
        },
        () => {
            //executes sync
            console.log(this.state.count)
        }
        )
        //executes async
        console.log(this.state.count)
    }

 

4. Calculate State Value Based on Current State

Let’s write a function that calls the incrementThree three times. Then in the button click call the incrementThree() function. The function is shown below:

    incrementThree(){
        this.incrementCount();
        this.incrementCount();
        this.incrementCount();
    }

When this code executes, we expect that the count value is incremented 3 times and therefore, 3 would be rendered. But no! Strangely, 1 is displayed!

This is because, Reacts groups multiple setState() calls into a single update, for better performance. So all the 3 setState() calls are done in a single go and the updated values are not carried over to subsequent calls. To fix this: when we want to update state based on the previous state, we need to pass a function to the setState() method rather than an object. This function takes an argument of the previousState. The modified function is given below:

    //Updating a state based on previous state
    incrementCount(){
        this.setState((previousState) => ({
            count: previousState.count + 1
        }))
    }

So the arrow function has access the previous state and uses it to calculate the new state.

Note: the second parameter to the arrow function is the props object. We’ll talk about this more in subsequent lessons.

 

5. Summary on setState()

So we provide a brief summary on use of setState() function below

  1. Never alter the state directly, always make us of the setState() method
  2. If a code has be be executed after the state is changed, then place this code in a callback function which is a second parameter to the setState method
  3. If state has to be updated based on it’s previous value, then pass in a function to the setState() method. This function takes the previous state as parameter and used it to compute the next state.
0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments