Getting Started with React useReducer Hooks

React's useReducer hook is a very interesting alternative to useState and can be a far more compact solution in some cases.

The React useReducer hook is a very interesting hook that is basically an alternative to useState.

The hook looks something like this:

const [state, dispatch] = useReducer(reducer, initialState)

Let's explore it a bit further in order to understand it.

So, what is a reducer?  A reducer is typically a switch statement that will change what happens to the state depending on what parameter (called action) is passed into the dispatch function, which is like a setState function.

A simple reducer will look something like this:

const reducer = (state,action) => {
    switch (action.type){
        case "increase":
            return {...state, count: state.count + 1};
        case "decrease":
            return {...state, count: state.count - 1};
        default:
            break;
    }
}

Then, for instance, to decrease the count by 1 using the action type "decrease", we would use our dispatch like this:

dispatch({type: "decrease"});

We can then get the count simply by using:

{state.count}

The full code might look something like this:

import React, { useReducer } from 'react'

const reducer = (state,action) => {
    switch (action.type){
        case "increase":
            return {...state, count: state.count + 1};
        case "decrease":
            return {...state, count: state.count - 1};
        default:
            break;
    }
}

const initialState = {
    stuff: "stuff",
    count: 0
}

const myComponent = () => {
    const [state, dispatch] = useReducer(reducer, initialState);

    return (
        <div>
            <button onClick={()=>dispatch({type: "decrease"})}>Decrease</button>
            <span>Count: {state.count}</span>
            <button onClick={()=>dispatch({type: "increase"})}>Increase</button>
        </div>
    )
}

export default myComponent;

Another trick for handling forms, especially ones with lots of fields, is the following:

const reducer = (state,action) => {
    switch (action.type){
        case "field":
            return {
                ...state,
                [action.field]: action.value
            };
        default:
            break;
    }
}

We can then edit, for example, our email field using the following dispatch:

onChange={e=>dispatch({type: "field", field: "email", value: e.target.value })}

This can be used to replace a lot of useState hooks for each field in a form.

You can also change multiple parts of the state at once.

const reducer = (state,action) => {
    switch (action.type){
        case "loading":
            return {
                ...state,
                loading: true,
                data: null,
                authorized: false
                title: "Loading..."
            };
        default:
            break;
    }
}

While most of the stuff you can do with useReducer can be done with useState, useReducer may be much neater in some cases.

You've successfully subscribed to The VN Vine
Great! Next, complete checkout to get full access to all premium content.
Error! Could not sign up. invalid link.
Welcome back! You've successfully signed in.
Error! Could not sign in. Please try again.
Success! Your account is fully activated, you now have access to all content.
Error! Stripe checkout failed.
Success! Your billing info is updated.
Error! Billing info update failed.