DEV Community

samanthamarberger
samanthamarberger

Posted on • Updated on

useState Hook: A staple that every React user should know how to use

So you want to add dynamic functionality to your web application using React?

Let's talk about the useState hook. The useState hook is a function that can be imported from react. This function allows you to set a component's state, or value, but the value can be changed by some type of action on the users end. This change also causes an automatic re-render of the page, allowing information on the DOM to be updated anytime the state variable is changed!

How do I import the useState hook?

  1. You must import it from React.
  2. Call and initialize your state variable.

Take a look at the code below!

import React, { useState } from "react";

function Counter() {
    const [counter, setCounter] = useState(0);
Enter fullscreen mode Exit fullscreen mode

The first line of code here imports the ability to use state, the line of code within the counter function is initializing the variable. The variable is set as an object, including the variable name, as well as the setter function, in this case "setCounter". That setter function is what is used to update/ change the counter variables value.

In the code above, I created a function component that outputs the counter value, which as of now is 0. When I initialized my counter variable it was set with a const. Even though the value of the variable can change, const is used rather than let because useState is an updating function. The variable does not get reassigned through the "=" operator, but rather updated by using the setter function like so.

setCounter(1);
Enter fullscreen mode Exit fullscreen mode

The counter variable would now return "1".

The "counter" is the container for the value, in this case 0. The second variable, "setCounter" is the updating function. Both are required when using the useState hook.

When to not use state!

The useState hook is a very powerful tool; however, if it is used too often and in the wrong circumstances your code can get buggy quickly and it would be a painful debugging process.

Here are three general things to check for to determine if state would be useful or not. They are found in Thinking in React.

1. Does your state variable get passed as a prop between components?
If it is, it is likely not going to be state. State should only be updated and used within the component it is declared in.
2. Is your state variable truly a constant?
If your state does not change and there is no need for a set function to update your state variable, you do not need a state variable. A simple constant will do!
3. Can your value be computed from any other state or props in the component?
Basically, don't over use state. If you already have an existing state and you want to create another state variable, make sure it is not one that can be derived from your original state.

Examples of using state:

I am going to discuss two different situations in which using the useState hook would be helpful. The first is a basic counter function to help us get a better understanding of useState. The second will be an example from a recent project of mine where we will go over using useState with arrays.

The simple counter function:

Let's create a counter function that allows you to increase your output number by one each time a "plus one" button is pressed. This set up is shown above when I go over how to import useState but I will add a few more things and discuss it once more below.

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

    return (
        <div>
            <h1>{counter}</h1>
            <button>+1</button>
        </div>
    );
}
Enter fullscreen mode Exit fullscreen mode

In the setup above, I have a variable being set, using the useState hook, to 0. I am returning the counter value as well as a button that says "+1". This button does not yet have functionality, let's add some!

 function addOne() {
        setCounter(counter + 1);
    }
Enter fullscreen mode Exit fullscreen mode

Here I built a function that when called upon takes the counter variable and updates it to the assigned counter variable plus one. When I call the setter function, in this case "setCounter", the page re-renders and the DOM is automatically updated. I need to call the setCounter() function, this will be done by creating an onClick for my button.

<button onClick={addOne}>+1</button>
Enter fullscreen mode Exit fullscreen mode

Now the setCounter function is called and the value is updated!

Using useState with arrays

Arrays can be updated using the useState hook as well. In a recent project of mine I created a web application that allows me to store all of my favorite paintings and add paintings to my collection. The paintings are stored on a server; however, I want them to be stored in an array. To do this, I must first use the useState hook to define the array.

 const [paintings, setPaintings] = useState([]);
Enter fullscreen mode Exit fullscreen mode

I created a painting variable and a setter function for that variable and I set it to an empty array.

Through a fetch request I was able to pull the information from my server and use my setter function to put it into an array. I don't want to distract from the useState hook functionality, so I am going to simplify and make an array of paintings and use my setter function to update the array.

const paintingsArray = ["Starry Night", "The Scream", "Royal Red and Blue"];

setPaintings(paintingsArray);
Enter fullscreen mode Exit fullscreen mode

Now my paintings array is no longer an empty array, but an array of three values.

Let's say I wanted to add another painting to the array. I simply need to use the spread operator, making a copy of my paintings, and add the new element to that array. I would then call the setPaintings function and give it the new array.

newPaintingsArray = [...paintings, newPainting];
setPaintings(newPaintingsArray);

Enter fullscreen mode Exit fullscreen mode

The use of the setter function caused a re-render leading to an automatic update of the DOM. This allows my web application to update the paintings right away without any refreshing from the user.

Setting state is an asynchronous process.

Because setting state is asynchronous, the function of setting the state will not be immediately executed. React waits until other processes or functions are completed before it changes state. This is an important thing to note; if you try to set state more than once within a function, the output will likely not be your desired output.

For example, say we have a button on our counter function that when clicked adds 1 to the value and then multiplies it by 5. Let's see what would happen if you put those two commands separately in the same function:

 function addOneMultiplyFive() {
        setCounter(counter + 1);
        setCounter(counter * 5);
    }

return (
        <div>
            <h1>{counter}</h1>
            <button>+1</button>
            <button onClick={addOneMultiplyFive}>Add one and multiply by 5</button>
        </div>
    );

// If I click the "Add one and multiply by 5 button"
// => 0

// If I click the "+1" button first and then the "Add one and multiply by 5" button
// => 5
Enter fullscreen mode Exit fullscreen mode

React is not updating state in between the addition of 1 and the multiplying of 5 in the "addOneMultiplyFive" function. Therefore, the counter value being multiplied by 5 is the counter value before the button was clicked.

Well, there you have it! Hopefully you have a better understanding of how and when to use state variables. Good luck with your next React project!

Top comments (0)