DEV Community

Cover image for UseState - React Hook
Supriya M
Supriya M

Posted on

UseState - React Hook

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.

<!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>
Enter fullscreen mode Exit fullscreen mode

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

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>
  );
}
Enter fullscreen mode Exit fullscreen mode

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

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.

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>
  );
}
Enter fullscreen mode Exit fullscreen mode

Live code 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 if you have any queries. Happy coding 💻

Peace ✌

Top comments (0)