Using the State Hook
# 02. Using the State Hook
import React, { useState } from 'react';
function Example() {
// Declare a new state variable called "count"
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
We'll start learning Hooks by comparing this code to an equivalent class example.
# Equivalent Class Component Example
class Example extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
}
render() {
return (
<div>
<p>You clicked {this.state.count} times</p>
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
Click me
</button>
</div>
);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
The state starts as { count: 0 }, and we increment state.count when the user clicks a button by calling this.setState(). We'll use snippets from this class throughout the chapter.
# Hooks Don't Work Inside Classes
Hooks don't work inside class components. But you can use them instead of writing classes.
# What Does Calling useState Do?
It declares a "state variable". Our variable is called count but we could call it anything, like banana. This is a way to "preserve" some values between function calls -- useState is a new way to use the exact same capabilities that this.state provides in a class. Normally, variables "disappear" when the function exits, but state variables are preserved by React.
# What Arguments Does useState Accept?
The only argument to the useState() Hook is the initial state. Unlike classes, the state doesn't have to be an object. We can keep a number or a string if that's all we need. In our example, we just need a number for how many times the user clicked, so we pass 0 as the initial state. (If we wanted to store two different values in state, we would call useState() twice.)
# What Does useState Return?
It returns a pair of values: the current state and a function that updates it. This is why we write const [count, setCount] = useState(). This is similar to this.state.count and this.setState in a class, except you get them in a pair.
# Understanding useState
Now that we know what the useState Hook does, our example should make more sense:
import React, { useState } from 'react';
function Example() {
// Declare a new state variable called "count" const [count, setCount] = useState(0);
2
3
4
We declare a state variable called count, and set it to 0. React will remember its current value between re-renders, and provide the most recent one to our function. If we want to update the current count, we can call setCount.
Note
You might be wondering: why is
useStatenot namedcreateStateinstead?"Create" wouldn't be quite accurate because the state is only created the first time our component renders. During the next renders,
useStategives us the current state. Otherwise it wouldn't be "state" at all! There's also a reason why Hook names always start withuse. We'll learn about this in the Rules of Hooks (opens new window).
# Using Multiple State Variables
Declaring state variables as a pair [something, setSomething] is handy because it lets us give different names to different state variables if we want to use more than one:
function ExampleWithManyStates() {
// Declare multiple state variables
const [age, setAge] = useState(42);
const [fruit, setFruit] = useState('banana');
const [todos, setTodos] = useState([{ text: 'Learn Hooks' }]);
2
3
4
5
In the above component, we have age, fruit, and todos as local variables, and we can update them individually:
function handleOrangeClick() {
// Similar to this.setState({ fruit: 'orange' })
setFruit('orange');
}
2
3
4
You don't have to use many state variables. State variables can hold objects and arrays just fine, so you can still group related data together. However, unlike this.setState in a class, updating a state variable always replaces it instead of merging it.
We provide more recommendations on splitting independent state variables in the FAQ (opens new window).
Putting all state in a single
useStatecall, or having auseStatecall for every individual field can both work. Components tend to be most readable when you find a balance between these two extremes, and group related state into a few independent state variables. If the state logic becomes complex, we recommend managing it with a reducer (opens new window) or a custom Hook.