As your component grows, so does the logic around the state variables. Each state could be associated with multiple event handlers, updating the state to different values. For example, here is a counter that could add, subtract, and reset the state count
.
1import { useState } from "react";
2
3export default function Counter() {
4 const [count, setCount] = useState(0);
5
6 function handleAdd() {
7 setCount(count + 1);
8 }
9
10 function handleSubtract() {
11 setCount(count - 1);
12 }
13
14 function handleReset() {
15 setCount(0);
16 }
17
18 return (
19 <div>
20 <p>Count: {count}</p>
21 <button onClick={handleAdd}>Add</button>
22 <button onClick={handleSubtract}>Subtract</button>
23 <button onClick={handleReset}>Reset</button>
24 </div>
25 );
26}
In this example, there are three different event handlers, handleAdd()
, handleSubtract()
, and handleReset()
tied to the state count
. As the component grows in complexity, managing so many states and the various event handlers can get overwhelming.
In this case, you can merge all the state updating logic into one single function, referred to as the reducer, which can be placed outside of the component, and imported when needed.
1src
2├── App.jsx
3├── assets
4│ └── react.svg
5├── components
6│ └── Counter.jsx <===
7├── index.css
8├── main.jsx
9└── reducers
10 └── countReducer.js <===
Replacing useState with useReducer
To start using reducer, the first thing you should do is replacing useState()
with useReducer()
like this:
components/Counter.jsx
1import { useReducer } from "react";
2import countReducer from "../reducers/CountReducer";
3
4export default function Counter() {
5 const [count, dispatch] = useReducer(countReducer, 0);
6
7 . . .
8}
useReducer()
is another React hook used to create states similar to useState()
, except it accepts two arguments.