Welcome back to our Exploring React Hooks series! Today, we'll explore one of the most fundamental and widely used hooks: useState.
What is the useState Hook?
The useState hook is a built-in function that allows us to add state to a functional component.
Prior to the introduction of hooks, state management was primarily achieved through class components in React and the use of the this.setState()
method. With the introduction of useState hook, the process of managing state has become simpler. The useState hook provides a more straightforward and concise syntax for managing state in functional components.
const [state, setState] = useState(initialState);
Getting Started with useState:
We'll be using the example of Counter App which we created earlier. Let's take a look:
🪝Importing and Initializing useState
At the top of the component, we will first import
the useState
Hook.
The convention to name state variables is like [something, setSomething]
using array destructuring. When we declare a state variable with useState
, it returns a pair — an array with two items:
The current state value.
A function that lets us update the state.
We also have to assign an initial value to the state
variable.
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
In this example, we imported the hook at the top level and initialized the state variable count
to 0 using the useState hook. The useState
function returned an array with two elements: the current state value (count
) and a function (setCount
) to update that state value.
🪝Reading State:
We can now include our state anywhere in our component.
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
</div>
);
}
We rendered a <div>
, where the current value of count
is displayed inside a <p>
element. Initially, the value of count
was set to 0
.
🪝Updating State:
To update the state, we will use the setCount
function provided by the useState hook. Let's create an increment
function, where we will call setCount
and pass in the new value by incrementing the current count by 1. We will also create a <button>
element with an onClick
event handler that will trigger the increment
function.
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
const increment = () => {
setCount(count + 1);
};
return (
<div>
<p>Count: {count}</p>
<button onClick={increment}>Increment</button>
</div>
);
}
When the component is rendered, the initial value of count
is displayed.. Clicking the "Increment" button calls the increment
function, which updated the value of count
and this triggered a re-render of the component with the updated value displayed.
🪝Creating Multiple State Variables:
We can use the useState
hook multiple times in a single component to manage different state variables independently. Each state variable will be tracked separately and can be updated using its respective setter function.
import React, { useState } from 'react';
function Magic() {
const [name, setName] = useState('Harry Potter');
const [school, setSchool] = useState('Hogwarts');
const [house, setHouse] = useState('Gryffindor');
const [spell, setSpell] = useState('Expelliarmus');
return (
<div>
<p>
I am {name}, a student of {school}. I belong to the {house} house, and
and I've mastered the spell {spell}.
</p>
</div>
);
}
export default Magic;
In this example, we're managing four independent state variables: name
, school
, house
and spell
. Each state has its own setter function (setName
, setSchool
, setHouse
, and setSpell
) to update the corresponding value.
Let's check out the Output:
🪝Creating a single Hook that holds an object:
We can also use just one state and include an object!
Let's take the previous example and modify it. We'll create a state variable called wizard
, which will be an object with the properties name
, school
, house
, and spell
.
import React, { useState } from 'react';
function Magic() {
const [wizard, setWizard] = useState({
name: "Potter",
school: "Hogwarts",
house: "Gryffindor",
spell: "Expelliarmus"
})
return (
<div>
<p>
I am {wizard.name}, a student at {wizard.school}. I belong to the {wizard.house} house, and I've a mastered the spell {wizard.spell}.
</p>
</div>
);
}
export default Magic;
Since we were tracking a single object, we needed to reference that object and the object's property rendering the component. We accessed the specific properties within the object using the dot operator.
This would result in a similar output as the previous one.
🪝Updating Objects and Arrays in State
Let's say we only want to update the spell of Harry to "Expecto Patronum".
We can call setSpell({spell: "Expecto Patronum"})
,but doing so would remove the name
, house
, and school
from our state.
When state is updated, the entire state gets overwritten.
What we can do is take the help of the JavaScript spread operator.
import React, { useState } from 'react';
function Magic() {
const [wizard, setWizard] = useState({
name: "Potter",
school: "Hogwarts",
house: "Gryffindor",
spell: "Expelliarmus"
})
const updateSpell = () => {
setWizard(previousState => {
return { ...previousState, spell: "Expecto Patronum" }
});
}
return (
<div>
<p>
I am {wizard.name}, a student at {wizard.school}. I belong to the {wizard.house} house, and I've a mastered the spell {wizard.spell}.
</p>
<button type="button" onClick={updateSpell}>
Change Spell
</button>
</div>
);
}
export default Magic;
Because we needed the current value of state, we passed a function into our setSpell
function. This function received the previous value.
We then returned an object, spreading the previousState
and overwriting only the spell that needed to be updated.
Here, we created a button Change Spell
that would update the spell
property to "Expecto Patronum" while keeping the other properties unchanged.
To Summarize
The useState
hook is a powerful tool that simplifies state management in React functional components. It allows us to add and update state variables within our components, resulting in cleaner code and improved performance.
References
Thank you for taking the time to read this blog. I hope you found it informative and enjoyable!
Share your thoughts and feel free to connect with me on Twitter.
In our next article, we'll explore another essential hook: useEffect. Stay tuned!
Catch you guys on the next one. Cheers .. ✌️