React Hooks: useState
Tags: react, javascript, reacthooks, beginners
Published: 2020-08-18 21:42:24

Before I knew that React Hooks had even existed, I used to read advise like, "*Always use functional components instead of class components in React.*" Which means always declare your components as functions instead of as classes. Or in code: 
```javascript
//use
const Component = ()=>{
  // return code here 
}

//instead of 
class Component extends React.Componet{
    render(){
       // return code here 
    }
}
```
I tried to follow that advice for a little while. However, the moment I wanted to use `state` in my component, that advice seemed useless. I had to refactor my code and use a class component instead of a functional component. I thought that was the only way to use `state` or any of the [lifecycle methods](https://www.w3schools.com/react/react_lifecycle.asp) in React. Little did I know.

I then learned about Hooks, and that advice started to make a lot more sense.

The first few things that I have learned about React Hooks are:
1- Hooks allow us to use `state` and other features without having to write a class.
2- We only call them from functional components. 
3- We only call them at the top level, not inside loops, conditions, or nested functions.

let us write a simple class component that changes the background color of a `div` element and then see how we can refactor it to use the `useState` hook.

```javascript
class App extends React.Component {
    constructor(props){
      super(props);
      this.state= {
         backgroundColor: "lightblue",
      }
    }
    changeBackgroundColor = ()=>{
     this.setState({ backgroundColor: getRandomColor() })
    }
    render(){
        return(
         <main>
             <div 
                style={{backgroundColor:this.state.backgroundColor }} 
                className="circle"
              />
             <button onClick={this.changeBackgroundColor}>Change Color</button>
         </main>
        )}
}
const getRandomColor = ()=>{
   return "#" + Math.random().toString(16).slice(2,8);
}
```
{% codepen https://codepen.io/hajarnasr/pen/NWNNVgY default-tab=js,result %}

That looks like a lot of code for something that does nothing but randomly change a background color, right?

Let's see the changes that will happen when using the `useState` hook.  

```javascript
import React, { useState } from 'react';
const App =()=> {
    // 1
    let [backgroundColor, setBackgroundColor] = useState("lightblue");
    const changeBackgroundColor = ()=>{
      // 2
      setBackgroundColor(getRandomColor())
    }
    return(
      <main>
          {/* 3 */}
          <div 
            style={{backgroundColor:backgroundColor}} 
            className="circle"
          />
          {/* 4 */}
          <button onClick={changeBackgroundColor}>Change Color</button>
      </main>
    )}
```
**First**, we replaced four lines of writing a constructor and using `this.state` with just one line.
```javascript 
// Old code
constructor(props){
      super(props);
      this.state= {
         backgroundColor: "lightblue",
     }
}

// New code
let [backgroundColor, setBackgroundColor] = useState("lightblue");
```
**Second**, we don't have to use `this.setState` to update the `state` variables anymore.
```javascript
// Old code
this.setState({ backgroundColor: getRandomColor() })

//New code
setBackgroundColor(getRandomColor())
```
**And finally**, we no longer have to get confused by using lots of `this` and `this.state.<variable_name>`
```javascript
// Old code
 onClick={this.changeBackgroundColor}
 style={{backgroundColor:this.state.backgroundColor}}

// New code
 onClick={changeBackgroundColor}
 style={{backgroundColor:backgroundColor}} 
```
Let's take a closer look at this line of code:
```javascript
let [backgroundColor, setBackgroundColor] = useState("lightblue");
```
What do you think this line does? And what if we wanted to change, let’s say, the font-family instead of the background-color, what do you think would change? 

Answering the second question first, if we wanted to change the font-family we would write:
```javascript
Let [fontFamily, setFontFamily] = useState("Arial"); // setting Arial as the initial value of the font-family.

//Or 
Let [font, setFont] = useState("Arial"); // you can name your variables whatever you want.
```
Back to our first question. What do you think that line of code does?
```javascript
let [backgroundColor, setBackgroundColor] = useState("lightblue");
```
That line does three things, actually.
1- It declares a variable named `backgroundColor`. 
2- It gives that variable an initial value of `lightblue`.
3- It declares a function named `setBackgroundColor` that is now responsible for updating the `backgroundColor`’s value whenever we need.

So now, why does this happen?

When we call the `useState` hook and pass it a value, it returns an array of two items. The first item is a `state` variable and set to the value that is passed to the `useState` hook. The second item is a function that is responsible for updating the first variable. 

When we write, ```javascript
let [backgroundColor, setBackgroundColor] = useState("lightblue");
```
we use the [array destruction](https://javascript.info/destructuring-assignment) to assign the `backgroundColor` variable and the `setBackgroundColor` function to the two items of the array that's returned from calling the `useState` hook.

The last thing I want to mention here is that we can use the `useState` hook multiple times in our components.

If we wanted to change the background-color, the font-family and the border of a component we would write something like this:
```javascript
const [backgroundColor, setBackgroundColor] = useState("yellow");
const [fontFamily, setFontFamily] = useState("Arial");
const [borer, setBorder] = useState("1px solid teal");
```
Then use all the `setBackgroundColor`, `setFontFamily`, and `setBorder` functions to update the background-color, the font-family, and the border, respectively.

I think that is all I know about the `useState` hook so far. 

Thank you for reading.