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>
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>
);
}
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
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>
);
}
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)