How to: React Hook useState
Tags: react, javascript, webdev, beginners
Published: 2023-05-09 20:22:47

## 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](https://www.freecodecamp.org/news/react-hooks-fundamentals/#:~:text=React%20Hooks%20are%20simple%20JavaScript,updater%20function%20to%20update%20it.)

##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`: 

```react
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>
   );
};
```
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:

```react
import React, { useState } from 'react'
```

###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.](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment) This is what that would look like:

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

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:

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

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:

```react
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>
   );
};
```
##Mutating State!!


![It's a Trap!](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s98ezens59sk4zid2juv.gif)

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](https://react.dev/learn/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: 
```react 
function handleClick () {
   count++
   setCount(count); 
}
```
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

```react
import React, { useState } from 'react'
```

####3. Declare it

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

####4. Set it

```react
setCount((count) => count + 1);
```

Hopefully this helps. Good luck on your coding journey!
 
##References
- https://react.dev/learn/thinking-in-react#step-3-identify-the-minimal-but-complete-representation-of-ui-state
- https://www.freecodecamp.org/news/react-hooks-fundamentals/#:~:text=React%20Hooks%20are%20simple%20JavaScript,updater%20function%20to%20update%20it.
- https://legacy.reactjs.org/blog/2019/02/06/react-v16.8.0.html
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment
- https://react.dev/learn/updating-objects-in-state