UseState - React Hook
Tags: react, usestate, hooks, beginners
Published: 2021-05-17 08:44:32

As an introduction to React Hooks, the first hook we come across is useState().

In order to understand how useState works, we shall create a simple application in JavaScript. Using the understanding of this implementation, we shall replicate the same logic into React.

## Counter app using JavaScript.
```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Counter App</title>
</head>
<body>
    <p class="txt-count">You clicked 0 times</p>
      <button class="btn-click">
        Click me
      </button>
</body>
<script>
    const btn = document.querySelector(".btn-click");
    const outputTxt = document.querySelector(".txt-count");
    let count = 0;

    btn.addEventListener("click",() => {
        count = count + 1;
        outputTxt.textContent=`You clicked ${count} times`;
    })
</script>
</html>
```
Here, we define 2 classes: `txt-count` and `btn-click` within html `<body>` and implement the counter logic using the same classes with JavaScript enclosed in `<script>`. Each time the button is clicked, the count variable is incremented by one and the _whole text_ within `<p class="txt-count">` would change.

## Counter app using ReactJS

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

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

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count => count + 1)}>
        Click me
      </button>
    </div>
  );
}
```

The above code snippet creates a simple react app which increments the `count` value each time the button `Click me` is clicked. Let us break it down and understand how *useState* works.

The function useState() accepts 1 parameter which is the initial value of the state. It returns an array with 2 values. In our example, the 2 values are `count` and `setCount`. 

`count` is the actual **state**. It contains the latest value of the counter based on the number of clicks. `setCount` is a special function which is used to update the latest value for `count`. There are 2 ways to update the state using `setCount`. Either we can pass the latest value of count as `setCount(count + 1)` or we could pass a callback function which takes the previous value of the state and update the same as `setCount(previousValue => previousValue + 1)`. 
As a result of useState(), `count` value would get updated and the current value is displayed within `<p>` tag.

When the state variable is updated, in order to update the value of `count` on the UI, the whole component `Counter()` is re-rendered. Hence react hooks can only be used within functional Components and it would re-render after each state updation.

In terms of displaying the output, both the apps (JavaScript and React) presents the same value.

### Output

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fqja3myhalcmtbeiqu78.png)

## useState with Array and Object

The above example dealt with the state variable of type `number`. While using primitive datatypes, state updations are simple. When we deal with structural types: arrays or objects, we need to make sure that the updated value is not modifying the current state but changing the state entirely. In other words, the state variable must be immutable. Otherwise the re-render wouldn't take place and hence the state value is not updated on the UI.

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

function FruitBasket() {
  const [fruits, setFruits] = useState([]);
  const [fruitName, setFruitName] = useState("");

  const addFruit = () => {
    /* Improper updatiion of state - will result in errors
    setFruits((fruits) => (fruits[fruits.length] = fruitName));
    setFruits((fruits) => fruits.push(fruitName));
    */
    
    // Acceptable solutions
    setFruits((fruits) => fruits.concat(fruitName));
    // Array.concat returns a new array

    setFruits([...fruits, fruitName]); 
    // Creating a new arry using the concept of destructuring
  }

  return (
    <div>
    <h2>Fruit basket</h2>
      {fruits.map(fruit => (
        <p>{fruit}</p>
      ))}
      <input type="text" value={fruitName} placeholder="Add new fruit" onChange={(e) => setFruitName(e.target.value) }/>
      <button onClick={addFruit}>Add to Fruit Basket</button>
    </div>
  );
}
```
[Live code](https://codesandbox.io/s/usestate-fruitbasket-ijdrd) for the above program.

In the above program, `fruits` is a state variable which contains an array of fruit names. The initial value for this state is an empty array `[]`. We have another state `fruitName` which accepts user input in order to add a new fruit into this fruit basket.
In order to add this new `fruitName` within the `fruits` array, we would need to call `setFruits`. On clicking the button _Add to Fruit Basket_, `addFruit()` is executed. 

`addFruit()` contains 4 ways to update the `fruits` array. Note that the first 2 approaches are trying to modify the same array whereas the later 2 approaches are creating an entirely new array along with `fruitName`. Hence we need to make sure that the **state variable is immutable**.

Similar approach needs to be followed while dealing with objects as well. When the state changes, an entirely new object with the updated value must be passed to the state setter function.

With this, you would be able to get started with development in React using hooks. Most of the simple applications can be developed using appropriate state variables. As shown in the above example, we can use more than 1 useState for various purposes within a single functional component.

Get started with React and let me know if you found this article to be useful! Reach out to me on [Twitter](https://twitter.com/supminn) if you have any queries. Happy coding 💻

Peace ✌