Working with useState in React

Reading Time: 4 minutes

Introduction

Do you have data in your component which changes over time? And by using normal variables you are not able to reload your component. This issue can be easily resolved by the useState hook. This hook reloads the component whenever there are any changes in the state thereby updating your user interface with the latest value. That is the changes enable reloading the component and reflect those changes in the user interface. In such a situation you should always prefer to use this hook instead of using normal variables.

What is useState?

useState is a react hook that allows you to create state variables. Hooks can be used only within functional components, not with class components. By using useState in a component, it allows that component to have a dedicated state of its own. Let us see how we can use it.

Syntax

Here is the syntax for it:

const [state, setState] = useState(initialstate)

On the left side, we see state and setState in the square brackets. The first element holds the initial value and the second element is basically a function that is used to update the state.

This syntax is called array destructuring which means we are making two new variables: first is state and second is setState.

As you can see, inside the useState we provide the initial value for the state. 

Calling the useState declares a state variable.

This useState returns a pair of values: the current state and the function that updates it.

Demo of useState

Let us first create a react application. Here is the command for creating a new application:

npx create-react-app projectName

Note: While choosing a project name ensure that you lowercase letters only. With an upper case, you will get an error creating the application

Move into your project directory.

cd projectName

Now open the app.js file.

Let us define a state where we update its value and reset it.

First, we need to import the useState like this:

import { useState } from "react";

Then in the function add the following lines of code.

function App() {
  const [counter, setCounter] = useState(0);

  function counterHandler() {
    setCounter(counter + 1);
  }

  function resetHandler() {
    setCounter(0);
  }
  return (
    <div className="container mt-3">
      <h2>Hi,this is a state demo</h2>
      <p>Counter value: {counter}</p>
      <button type="button" class="btn btn-primary mr-2" onClick={counterHandler}>Update Counter</button>
      <button type="button" class="btn btn-primary" onClick={resetHandler}>Reset Counter</button>
    </div>

  );
}

Let us understand it. First, we are defining the state and setting the default value of the counter as 0.

Then we have a function counterHandler. It takes the state function setCounter which updates the value of the counter by adding 1 to it. 

Next, we have the resetHandler which also takes the state function, and this time we set the counter value to 0.

In the HTML part, we are displaying the counter value and two buttons that trigger the functions.

Now, try running the application using the npm start command.

Batching

Batching is when React groups multiple state updates into a single re-render for better performance. Let us understand it with an example. Here is an example code for it:

  const [item1, setItem1] = useState(0);
  const [item2, setItem2] = useState(0);

  console.log("Component renders: ", item1, item2);

  function handleClickWithPromise() {
    Promise.resolve().then(() => {
      setItem1(item1+1);
      setItem2(item2+1);
    });
  }
  function handleClickWithoutPromise() {
      setItem1(item1+1);
      setItem2(item2+1);
  }


  return (
    <div className="container mt-3">
       <p>Item1: {item1} Item2: {item2} </p>
       <button type="button" className="btn btn-primary mr-3 " onClick={handleClickWithPromise}>
         With promise
       </button>
      <button type="button" className="btn btn-primary mr-3 " onClick={handleClickWithoutPromise}>
        Without promise
      </button>
    </div>

Here we have two states, one for item1 and the second for item2. In both the functions, we are just incrementing the item value by 1. When you try running this code, the output will be the same for both the buttons but it’s the rendering that matters. Check your console on each button click. With promise, the component will render twice whereas in the case of without promise it will render once only. 

React batches updates made in a method like event handlers or lifecycle methods. But if the updates are within a callback or Promises then it doesn’t. To make batched updates for a code wrapped in promise, you need to use ReactDOM.unstable_batchedUpdates(). Like this:

function handleClickWithPromise() {
    Promise.resolve().then(() => {
      ReactDOM.unstable_batchedUpdates(() => {
        setItem1(item1+1);
        setItem2(item2+1);
      });
    });
  }

Now with this function, the component will re-render once only.

Also, if you want to update the state using the previous state, you can pass a function to setState. This is the concept of Functional updates where the function receives the previous value and returns the updated value. For example, if you want to update the counter value you can do it like:

function App() {
  const [counter, setCounter] = useState(0);

  return (
    <div>
      <p>Counter value: {counter}</p>
      <button type="button"  onClick={() => setCount(count => count + 1)}>Update</button>
      <button type="button"  onClick={() => setCount(0)}>Reset Counter</button>
    </div>
  );
}

Here, in the update button, you can see how we are updating the value using the previous state.

Conclusion

In this blog, we understood in which situation we should use the state and how to use it. We can also define multiple states in the same component. We also understood the concept of batching and how it affects performance. Remember you cannot use these hooks inside class components, they can be only used within functional components. To learn more about React hooks you can refer here.

Written by 

Kiran Jeet Kaur is working as a Software Consultant in Knoldus. Her practice area is Front End. She is always open to learn new things. Her hobbies include watching movies and listening to music.

Discover more from Knoldus Blogs

Subscribe now to keep reading and get access to the full archive.

Continue reading