DEV Community

Jesse Ilc
Jesse Ilc

Posted on

How to: React Hook useState

What, When, Why?

As a web developer, many are familiar with the Javascript library known as React. You may have also heard of React Hooks. Since their introduction in React 16.8 (released Feb. 16, 2019), they've become an integral part of the React environment. These Hooks can be extremely useful and provide a lot of functionality. In this blog, I will cover the React Hook known as useState discussing how to set it up and how to use it.

React Hooks

β€œReact Hooks are simple JavaScript functions that we can use to isolate the reusable part from a functional component. Hooks can be stateful and can manage side-effects.” - freecodecamp.org

What is useState?

The React Hook useState allows us to add and access the state of functional components. So how does this help us? It allows our data to be dynamic. Which in return, grants us the ability to re-render and update our application based on events or something that the user has done. Let's take for example a counter app. If a user clicks on a button to increment the counter we want to update the counter dynamically. We can do this with useState. When it comes to the debate whether to use prop or state, you can ask yourself these 3 questions:

The Questions

  • Is it passed in from a parent via props?
  • Can you compute it based on any other state/props in your component?
  • Does it remain unchanged over time?

If you answer no to all of these questions, then you should probably use useState.

The How To

Let's talk about how to incorporate useState into your code. We'll use our counter component from earlier as an example. Here's what that component might look like without useState:

import React from 'react'

function Counter () {

   let count = 0;

   function handleClick () {
      count++; 
   }

   return (
      <div>
         <p>{count}</p>
         <button onClick={handleClick}>press to increase</button>
      </div>
   );
};
Enter fullscreen mode Exit fullscreen mode

Although this is functional, our component is not actually re-rendering as we increment. Also, the count variable goes back to 0 as soon as we refresh the page. Let's add state to fix these issues.

Import it

First we need to import useState into our component. This is pretty straightforward; at the top of your code (or in whatever component you need it) you want to import it from React by using the destructing syntax (aka this one { } ). This is what that would look like:

import React, { useState } from 'react'
Enter fullscreen mode Exit fullscreen mode

Declare it as a variable

Next we want to replace our count variable with our useState variable. To do this, we can call the useState hook by using the array destructuring syntax. This is what that would look like:

const [count, setCount] = useState(0);
Enter fullscreen mode Exit fullscreen mode

The reason why we use brackets for useState is because it will always return an array with 2 variables:

  • a reference to the current value of that state in React's internals
  • a setter function so we can update that state

Technically, the name of the reference and setter function are arbitrary so feel free to call them whatever you like. As good practice you use the naming convention for the setter function as 'set' followed by the reference variable name. Another neat thing is that you can set the initial useState to various different data types; strings, objects, arrays, numbers, booleans, empty or not can all be set as the initial useState.

Setting the state

Now that we've called the useState hook into our component we need a way to update the state and re-render the page with the correct value. This is where our setter function comes in handy. All we need to do is pass our state and increment it by 1 inside our handleClick() function:

function handleClick() {
   setCount((count) => count + 1);
}
Enter fullscreen mode Exit fullscreen mode

After incorporating all these steps, we should now have a working increment button that updates our count state dynamically as the user clicks the button. Even if the page is refreshed the count state will remain the same. Here is the code as a whole:

import React, { useState } from 'react'

function Counter () {

   const [count, setCount] = useState(0);

   function handleClick () {
      setCount((count) => count + 1); 
   }

   return (
      <div>
         <p>{count}</p>
         <button onClick={handleClick}>press to increase</button>
      </div>
   );
};
Enter fullscreen mode Exit fullscreen mode

Mutating State!!

It's a Trap!

Let's talk about the setter function for one moment. From React's documentation, it's written:

"But you shouldn't change objects that you hold in the React state directly. Instead, when you want to update an object, you need to create a new one (or make a copy of an existing one), and then set the state to use that copy." - React Docs: Updating Objects in State

In the example earlier, our setter function does the following:

  • Creates a copy of the state
  • Add's 1 to the copy
  • Set's the copy state as the state

This is important to keep in mind. If I tried to just update the state like this:

function handleClick () {
   count++
   setCount(count); 
}
Enter fullscreen mode Exit fullscreen mode

the component doesn't actually re-render with a new value. The reason this happens is because we're not providing a new value to setCount when it's called. Even though we mutated the value, its value did not change in memory. Setting the state with the same value won't make React re-render our component.

Conclusion

So let's review.

1. When to useState

If you answer no to all of these:

  • Is it passed in from a parent via props?
  • Can you compute it based on any other state/props in your component?
  • Does it remain unchanged over time?

2. Import it

import React, { useState } from 'react'
Enter fullscreen mode Exit fullscreen mode

3. Declare it

const [count, setCount] = useState(0);
Enter fullscreen mode Exit fullscreen mode

4. Set it

setCount((count) => count + 1);
Enter fullscreen mode Exit fullscreen mode

Hopefully this helps. Good luck on your coding journey!

References

Top comments (0)