Before knowing about useState, let us quickly have a look on what actually react hooks are.
Hooks are new addition in React 16.8. Hooks are regular javaScript functions and are used in functional components. Hooks are used to manage and update state variables.
useState
useState hook allows us to have a state variable in functional components. useState always returns an array, so we need to destructure it before using them. First value in the array is known as "state variable" and second value as "updater function". State variable is used to hold the value of state and we can update the state variable using updater function.
Before using useState hook we need to import it from React.
import {useState} from "react";
We can initialize different types of value such as object, array etc., to the state variable using the useState hook or it can also be initialized with null value also.
// state variable is initialized with null value
const [state, setState] = useState();
// State variable is initialized with a string
const [name, setName] = useState("prashanth");
// state variable is initialized with a number
const [age, setAge] = useState(20);
// state variable, an array
const [names, setNames] = useState([]);
// state variable, an object
const [details, setDetails] = useState({name : prashanth , age: 21})
Instead of declaring too many useStates for creating multiple variables, we can also use arrays and objects which can hold multiple values at the same time.
Updating state variable :
// Here the state variable i.e., age is initialized with a number
const [age, setAge] = useState(18) ;
// When the button is clicked, it increments the age by 1 year
<button onClick={ () => setAge(age + 1) }>
add one year
</button>
Here setAge is the updater function which is used to update the state variable(age).
// import useState from React
import React, { useState } from "react"
function CodeExample() {
// here state is initialized with an empty string
const [name, setName] = useState("");
// here state is initialized with a number
const [age, setAge] = useState(20);
return(
<div className="CodeExample">
<h1>{ name }</h1>
<h1>{ age }</h1>
<input type="text" onChange={ (e) => setName(e.target.value) }/>
<button onClick={ () => setAge(age + 1) }>
add one year
</button>
</div>
);
}
This code snippet combines all the concepts we have learned so far, Here we can see how to use state variable in the actual code which is being rendered on to the screen and how state variables can be updated(hint : updater function).
Handling objects in useState :
While we can use too many useState hooks for holding multiple values using an object makes the job a lot easier. I know It's a bit confusing to update the state variable which contains an object.
The below code works fine at the first render, but would fail at the second render because we are essentially changing the structure of the object in the state.
import react, { useState } from "react";
function ObjectExample() {
const [details, setDetails] = useState({name : "prashanth", age: 20})
function handleChange() {
setDetails({age : details.age + 1 });
}
return (
<div className="ObjectExample">
<h1>Name : {details.name}</h1>
<h1>Age : {details.age}</h1>
<button onClick={handleChange}>
add one year
</button>
</div>
);
}
Here the state variable is initialized with an object which has two properties but when the state variable is updated, the initial object is replaced with a new object which only has one property and re-renders the component where the value of name is set to undefined.
{name : "Prashanth", age : 20} // initial object
{age : 21} // updated object
This issue can be solved using spread operator(...) which get all the properties of the initial object and the updated age property will override the age property.
function handleChange(e) {
setDetails(prevState => {
return { ...prevState, age : prevState.age + 1 }
})
}
Want to learn more about React Hooks, check out my blog on useEffect .