What is useReducer?
The useReducer hook in react is the useState hook. It provides an alternative way of managing state in your components.
useReducer
is great for managing complex state logic in your React application. And learning how to use this hook will help you write more readable and cleaner code.
In this tutorial, you will learn about the useReducer hook. You will learn what it's made up of. And how to use it in your React applications.
How to use the useReducer hook
When you initialize useReducer, you will often pass two arguments to it. These arguments are a reducer function and an initial state value.
const initialState = "my value"
useReducer(reducer, initialState)
useReducer
can also take a third argument, which is optional. This third argument is a function. React will set what the function returns as the initial state value.
function initStateFunc() {
// ...some code here
return "my value"
}
// useReducer with an optional third argument
useReducer(reducer, initialState, initStateFunc)
What does useReducer return?
Like useState, useReducer
returns an array with two items. The first item is the current state variable. And the second item is a dispatch function.
So when you initialize useReducer, you will end with something like this.
const [state, dispatch] = useReducer(reducer, initialState)
The four parts of useReducer
The useReducer hook contains four main parts.
- State (current state).
- Dispatch function.
- Reducer function.
- InitialState
The initialState
is the value of state when the component first renders. And state
is the current value of the state variable.
The reducer function
The reducer function handles the calculation of the new value of state.
It accepts two arguments - a state
(current state) and an action
.
Here is how you declare a reducer function.
function reducer(state, action) {
// ...code here
}
The updated state value will be dependent on the action passed to the reducer. Here is an example.
function reducer(state, action) {
const reducer = (state, action) => {
switch(action.type) {
case "ADD":
return {count: state.count + 1}
case "SUBTRACT":
return {count: state.count - 1}
default:
return state
}
}
}
The dispatch function
The job of the dispatch function is to send (or dispatch) an action
to the reducer function. It takes a single argument, which is the action
.
The value of the action
can be of any type. For example, it can be a string.
dispatch("ADD")
But, the convention is to write your action as an object with a type
property.
dispatch({ type: "ADD" })
A working example of useReducer
You are now familiar with the makeup of useReducer. If you need to, you can reread the explanation to get a better understanding.
Time to write some code. In this example, you will build a simple counter app.
What's the first thing to do to use a hook in React? If your answer is "import the hook", you are right.
import { useReducer } from 'react'
Then, create an initialState
variable. For the counter app, you can set the initial state as an object. The object has a count property with a value of zero.
const initialState = {count: 0}
The next step is to create your reducer function.
The counter app will have two buttons. When clicked, the first button adds one to the current number. And the second button subtracts one.
This means you will have two actions here - "ADD" and "SUBTRACT".
const reducer = (state, action) => {
switch(action.type) {
case "ADD":
return {count: state.count + 1}
case "SUBTRACT":
return {count: state.count - 1}
default:
throw new Error("Something went wrong")
}
}
With the initialState
and reducer
in place, you can now create the CounterComponent
.
After creating the component, you should initialize useReducer. And then add the appropriate dispatch functions to the buttons.
Your component should be like this.
function CounterComponent() {
const [state, dispatch] = useReducer(reducer, initialState)
return (
<>
<h1>{state.count}</h1>
<button onClick={() => dispatch({ type: "ADD" })}>ADD 1</button>
<button onClick={() => dispatch({ type: "SUBTRACT" })}>SUBTRACT 1</button>
</>
)
}
Your counter app is now complete. See the entire code for the app below. You can also click this link to run example code
import { useReducer } from 'react'
const initialState = {count: 0}
const reducer = (state, action) => {
switch(action.type) {
case "ADD":
return {count: state.count + 1}
case "SUBTRACT":
return {count: state.count - 1}
default:
throw new Error("Something went wrong")
}
}
function CounterComponent() {
const [state, dispatch] = useReducer(reducer, initialState)
return (
<>
<h1>{state.count}</h1>
<button onClick={() => dispatch({ type: "ADD" })}>ADD 1</button>
<button onClick={() => dispatch({ type: "SUBTRACT" })}>SUBTRACT 1</button>
</>
)
}
Conclusion
useReducer
offers an alternative way of managing states in your React application. You should consider using useReducer
when state contains complex logic.
In this tutorial, you have learned the following.
- What the useReducer hook is.
- How to use the useReducer hook.
- How to write the reducer and dispatch function.
If you have any further questions, you can ask them in the comment section below.