Contents
- Introduction to hooks
- What is the useReducer hook?
- What arguments are passed to useReducer hook?
- What is the return value of useReducer hook?
- How do you invoke dispatch?
- Reference
Introduction to hooks
This is the second post of my React hooks series. If you haven't read the first one which covers the most basic react hook useState
, check it out here. Today i am going to cover the basics of useReducer
hook.
What is the useReducer hook?
A hook
is a special function which enables one use state and other react features without writing ES6 class components which are generally considered confusing and difficult to master.
useReducer
hook is part of the React hooks API. It is a function which can be used instead of useState
if one is dealing with complicated state logic.
What arguments are passed to useReducer hook?
It takes three arguments and returns an array of two elements.
const [state, dispatcher] = useReducer(reducer, initArg, init);
reducer
The first required argument to useReducer
is a function usually referred to as reducer
. reducer
takes two parameters: state
and action
.
action
is used for specifying different ways state should be updated. reducer
function takes the form below and it is usually defined before the component.
function reducer(state, action){
if( action satisfies some condition){
// Do something
// Return new state
}
else if (action satisfies another condition) {
// Do something
// Return new state
}else{
// Do something
// Return new state
}
}
It is not uncommon to see switch
statement being used to determine action to take. More about action
HERE . You can also use anonymous function to define reducer
.
initArg
This is the second argument passed to useReducer
. If the third argument init
which is optional is omitted, initArg
is set as the initial state otherwise it is passed to init
.
init
This is the third argument to useReducer
and it is optional. It is a function passed to useReducer
if the initial state is to be arrived at through, in most cases a computationally expensive process. This function is invoked with the second argument to useReducer
initArg
passed to it as an argument and its return value is used for setting the initial state. It takes the form below.
function init(initArg){
// Do some expensive computation
// Return a value which is used for setting initial state
}
What is the return value of useReducer hook?
useReducer
returns an array of two elements. The first element of the array is the initial state and the second element of the returned array is the function you call if you want to specify what action to take. You can use array destructuring to give them meaningful names like:
const [state, dispatch] = useReducer(reducer, initArg);
How do you invoke dispatch?
You can invoke dispatch
if you want to update state. It takes one argument used for specifying action
. This argument is in most cases an object but it doesn't necessarily have to be. Passing an object enables you to specify an action as well as pass the data you need for setting/updating state.
dispatch({action: "add", value: 2})
In the call to dispatch
above, action is "add" and it is a string constant though it doesn't necessarily have to be and data used for setting or updating state is passed as value of the object property value
.
Code below illustrates how you can use useReducer
.
import React, { useReducer } from "react";
import ReactDOM from "react-dom";
function reducer(state, action) {
switch (action.type) {
case "add":
return state + action.value;
case "subtract":
return state - action.value;
default:
return state;
}
}
function App(props) {
const [count, dispatch] = useReducer(reducer, 10);
function increaseCountHandler(e) {
dispatch({ type: "add", value: 1 });
}
function decreaseCountHandler(e) {
dispatch({ type: "subtract", value: 1 });
}
return (
<div>
<p> {count}</p>
<p>
<button onClick={increaseCountHandler}> + </button>
</p>
<p>
<button onClick={decreaseCountHandler}> - </button>
</p>
</div>
);
}
const element = document.getElementById('root');
ReactDOM.render(<App />, element);
In the code above, i started by defining a reducer with two parameters: state
and action
. state
is the current state and the action
is an object which is passed to reducer using dispatch
, the function returned after calling useReducer
. Inside the App
component, reducer
function is passed to useState
as first argument and initial state is set to 10.
NOTE: I haven't passed the third optional argument init
to useReducer
. If we are to pass it, the second argument 10
will be used for invoking it and initial state is set to the return value.
Array destructuring has been used to unpack the return value of useReducer
.
Take note of how dispatch
is invoked in the event handlers. You invoke it with an object specifying action
and data
for updating state.
dispatch({action: "add", value: 1});
If you find this article useful, you can share it on Twitter. Someone might find it useful too or if you notice something which is technically inaccurate, you can leave a comment below.
Top comments (1)
Your useEffect was easy to understand, this is not; Having read it, I still don't understand its Usage - You could have put some use cases and examples where it is useful (otherwise no point, I will just read the React officials docs ?)