React Hooks Series: useState
Tags: react, javascript, webdev, beginners
Published: 2020-08-18 21:15:00

## Introduction

I have created a small timer app in Codesandbox:

[Timer CodeSandbox](https://codesandbox.io/s/timer-clone-l7vuy?file=/src/Timer.js)

{% codesandbox l7vuy %}

I am attempting to cover A LOT in this series of posts. I have included the link to the Codesandbox, so you are encouraged to fork it and play around with it. But if you don't understand everything quite yet, fear not! I promise to cover every single line of code you see.

These series of articles make a few assumptions: you have some experience with React and understand some of its core features (e.g. virtual DOM, class vs. functional component syntax, state management).

Alright, let's dive in!

# Part One - useState
In Part One of my React hooks series, we are going to focus on the useState hook.

Import useState from React
```javascript
import React, { useState } from "react";
```
React's useState accepts one argument, the initial state and returns a pair of values, the current state and a function to change the state.

```javascript
 const [input, setInput] = useState(0)
 const [counter, setCounter] = useState(null)
 const [start, setStart] = useState(false)
```
The intial state of `input` is `0`
The intial state of `counter` is `null`
The initial state of `start` is `false`

As you can see, the argument passed to useState doesn't have to be an object, it can be a number, or a string, a boolean, etc!

Let's pause for a moment and take a look at a Class component example, which might be helpful to those familiar with the Class syntax.

```javascript
class Example extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      input: 0,
      counter: null,
      start: false
    };
  }
```
The Class example does the exact same thing of setting initial state. But, and this my opinion, the useState hook version is much cleaner and easier to read!

Now what?

The current state of `input`, `counter`, and `start` is accessible throughout our functional component and can be used to evaluate expressions and display information in our render() method.

But the REAL POWER is being able to update the state however we please! 

Let's focus on creating a form responsible for setting our Timer and the intial values of `input` and `counter`:

```javascript
   <form onSubmit={(e) => handleSubmit(e)}>
        <h1>Timer</h1>
        <input 
          onChange={handleChange} 
          min="0" 
          type="number" 
          id="seconds" 
          placeholder="seconds" 
          style={{textAlign: "center", width: "5rem"}}
        />
        <input type="submit" value="Set Timer"/>
   </form>
```
Will render on our screen:

![Timer form rendered on screen](https://dev-to-uploads.s3.amazonaws.com/i/s5r8db4w5ikwv3lxmcve.jpg)

A couple notes
* `min="0"` on a form with a `type="number"` won't let the user select a number less than zero. Cool, huh?
* `onSubmit={(e) => handleSubmit(e)}` and `onChange={handleChange}` are different ways of writing the same thing. I haven't noticed behavioral differences, so if you are reading this and know the difference, please let me know in the comments!

Let's take a look at those functions, `handleChange` and `handleSubmit`:

```javascript
const handleChange = (e) => {
    setInput(e.target.value)
}
```
```javascript
const handleSubmit = (e) => {
    e.preventDefault() // stops the submit from performing a re-render
    setCounter(input)
    e.target.reset() // removes the input from the "seconds" form input
}
```

Finally! We are using our new fancy hook, useState! inside `handleChange` we call `setInput(e.target.value)`. This updates the current state to whatever is passed in (isn't it satisfying to watch the number on your screen change as your input changes?). Similarly, we call `setCounter(input)` inside `handleSubmit`.

Notice what's happening here: `handleChange` updates `input`, and then `handleSubmit` uses the value of `input` to set the state of `counter` with `setCounter`.

(Some readers might wonder why I have two different states for essentially the same value. Without getting into too many spoilers, it made sense for me to have two different versions of state to conditionally render elements on the screen. The value of `input` isn't affected by the timer, where as `counter` will change every second.)

Okay fine, let's talk about one of those conditional renders before we get to the final implementation of useState, `setStart`. 

```javascript
 {
   start === false && counter !== null && counter !== 0
   ? 
   <button style={{fontSize: "1.5rem"}} onClick={handleStart}>START</button> 
   : 
   null
 }

 {
   start === true && counter !== 0
   ? 
   <button style={{fontSize: "1.5rem"}} onClick={handlePause}>PAUSE</button> 
   : 
   null 
}
```
There's a lot to unpack here. First, I'm using something called a [ternary operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator#:~:text=The%20conditional%20(ternary)%20operator%20is,if%20the%20condition%20is%20falsy.) to evaluate a statement, using boolean values. 

Ternary operator syntax
`condition ? option1 : option2` 
If `condition === true` run the statement on the left `option1` and if `condition === false` run the statement on the right `option2`

In my examples:
First, I set a condition `start === false && counter !== null && counter !== 0`
If ALL of these conditions are true, run the code on the left:
`<button style={{fontSize: "1.5rem"}} onClick={handleStart}>START</button>`
If even ONE of these conditions is not true, run the code on the right:
`null`

It's a very similar situation for the PAUSE button. Basically what's happening is, I only show the START or PAUSE buttons based on certain conditions. 

Once the START button is rendered, the user can update or final state `start` by activating `onClick={handleStart}`

```javascript
const handleStart = () => {
    setStart(true)
}
```

If you recall, the initial state `start` is `false`. Here we set `start` to `true` and it will stay `true` until something else changes it. 

In the next article in this series we will get to see more calls to `setInput`, `setCounter` and `setStart` as we explore the useRef and useEffect hooks.

## Final thoughts

Thank you for reading my first entry in the React Hooks Series! As soon as I have the second entry complete, I will post it and update this post with the link. 

If you have any questions, suggestions, corrections or general comments, I WOULD LOVE to read them and hear more from all of you!

THANK YOU AND HAPPY CODING