Don’t Use in Production
At the time of this writing, Hooks are in alpha. Their API can change at any time.
I recommend you experiment, have fun, and use Hooks in your side projects, but not in production code until they’re stable.
Source Code and Demo
Here are the GitHub and Codesandbox links.
useReducer
The React docs have a counter app example demonstrating the useReducer
Hook.
For demo purposes, I styled it just a bit.
The component code
The JSX is simple: it displays the current count
with 3 buttons.
The Counter
component calls useReducer
with a reducer and initial state, which gives back an array with the current state
and a dispatch
function.
Clicking any of the buttons calls dispatch
with an action object.
The initial state
The reducer code
The reducer decides how state should change based on the existing state and action object it receives.
If you’ve worked with Redux, you know this setup.
We see it supports three actions: reset
, increment
, and decrement
.
reset
: Sets the count
to 0.
increment
: Increases count
by 1.
decrement
: Decreases count
by 1.
Any other action results in the reducer returning its given state
.
createReducer
You may also know about createReducer
.
function createReducer(initialState, handlers) {
return function reducer(state = initialState, action) {
if (handlers.hasOwnProperty(action.type)) {
return handlers[action.type](state, action);
} else {
return state;
}
};
}
It’s a helper function from the Redux docs that lets you describe reducers as mappings from action types to handlers.
No more switch cases
Instead of switch
cases, we can use functions for every action type.
An added bonus is that if the given action doesn’t match, createReducer
takes care of the default
case by returning state
.
Works with useReducer
Since useReducer
’s based on the same principles, they’re perfectly compatible!
I’ll create a new project file, createReducer.js
.
And export the helper function from it:
Then use it like so:
Cleaner reducers
This, in my opinion, is much nicer.
Just give it the initial state, and an object mapping action types to their corresponding functions.
You can access state
and action
in each of those functions, so you have all the info you need!
The functionality hasn’t changed at all.
Still Just a Reducer
This works because useReducer
doesn’t care how you create a reducer.
Whether it’s switch
, if/else
, or createReducer
, just make sure your end result is a reducer.
I hope you enjoyed this brief piece!