React useState Hook: what’s new and to use it
useState is the React Hook that allows you to manage the state within functional components.
useState
, like all other hooks, was introduced with React 16.8 and allows you to create stateful functional components. In fact, before React 16.8, to write a stateful component we were forced to create a class component extending the React.Component
class and use the setState
function. Keep in mind that, for the purpose of this guide, we assume that you already have a basic knowledge of what React Hooks are.
In the following sections we will see:
- a simple example of how to use the React hook
useState
- store multiple states using React
useState
- React hook
useState
compared to Class Components withsetState
function
How to use React useState
Let’s start immediately with a practical example:
import React, { useState } from 'react'
const Example = () => {
// create the "counter" state
const [count, setCount] = useState(0)
return (
<div>
<p>Button clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Count + 1
</button>
</div>
)
}
export default Example
This is the classic example of a button with a counter. After importing useState
from React, we created a simple functional component that renders a paragraph to displays how many times we clicked the button. In this way, the component becomes very short and the amount of boilerplate code is minimum.
Let’s see in more detail the useState
hook and how to initialize it:
const [count, setCount] = useState(0)
In one simple line of code, we are doing the following:
- create a
count
variable which will hold the value of our counter - create a
setCount
function to which we can pass the new counter value as an argument, and which will then allow us to change the state - initialize the state to 0 by passing it as an argument to the
useState(0)
hook.
Continuing with our example, we see that when the button is clicked we increment the counter by one by calling the setCount
function:
<button onClick={() => setCount(count + 1)}>
Store multiple states using React useState
From the example above it might seem that it is not possible to manage the state of multiple variables through useState
.
That’s not true. In fact, we can handle multiple variables within the same hook by passing an object inside the useState
hook.
For example, we can modify the previous example to handle the status of the two counters (firstCount
and secondCount
) that can be incremented by clicking on two different buttons:
import React, { useState } from 'react'
const Example = () => {
const [state, setState] = useState({ firstCount: 0, secondCount: 0 })
const { firstCount, secondCount } = state
return (
<div>
<p>First count: {firstCount}</p>
<p>Second count: {secondCount}</p>
<button
onClick={() => setState({ ...state, firstCount: firstCount + 1 })}
>
Increment first counter
</button>
<button
onClick={() => setState({ ...state, secondCount: secondCount + 1 })}
>
Increment second counter
</button>
</div>
)
}
export default Example
However, using this approach in complex components may be difficult to read. For this reason, there is also the useReducer
hook, which we will explain in another article, that is built for more complex state management.
React Functional Component with “useState” compared to Class Components with “setState”
Functional Components are often preferred by many developers over Class Components, because they are more concise and clear to read. In fact, the amount of boilerplate code to write is less and this, strange as it may seem, in very large projects makes the job easier.
Until the arrival of React 16.8, however, it was not possible to use functional components whenever we needed to add a state
to our component or manage anylifecycle hook
. Thanks to the introduction of Hooks, in fact, it is now possible to completely replace the use of the Component
class with functional components and related hooks.
Below, we compare two components that respectively do exactly the same thing. One is a Functional and the other is a Class Component.
Functional component with useState
hook:
import React, { useState } from 'react'
const Example = () => {
const [count, setCount] = useState(0)
return (
<div>
<p>Button clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Count + 1
</button>
</div>
)
}
export default Example
Class Component with setState
function:
import React, { Component } from 'react'
class Example extends Component {
constructor(props) {
super(props)
this.state = { count: 0 }
}
render() {
const { count } = this.state
return (
<div>
<p>Button clicked {count} times</p>
<button onClick={() => this.setState({ count: count + 1 })}>
Count + 1
</button>
</div>
)
}
}
export default Example
As we can see, we saved a considerable amount of code, and we only needed to implement state management!