2 use cases of the useReducer ReactJS hook

useReducer is a Hook that allows us to manage multiple states more efficiently, create complex state logic, and manage states that depend on previous states. The following two use cases are good examples of how we can make use of this hook.

u…


This content originally appeared on DEV Community and was authored by Damian Demasi

useReducer is a Hook that allows us to manage multiple states more efficiently, create complex state logic, and manage states that depend on previous states. The following two use cases are good examples of how we can make use of this hook.

useReducer use cases

  • Manage multiple states: modify an array
  • Modify complex states, such as arrays or objects: login form

Manage multiple states

useReducer can be used to simplify the way in which multiple states impact a piece of data. In this case, adding, removing, and clearing an array can be achieved by using useReducer instead of three separate states.

import { useReducer } from "react";

const myReducer = (prevState, action) => {
    let array;
    switch (action.type) {
        case 'ADD':
            array = [...prevState];
            array.push(action.payload);
            return array;
        case 'REMOVE':
            array = [...prevState];
            array.pop();
            return array;
        case 'CLEAR':
            return prevState = [];
        default:
            break;
    }
};

const UseCaseMultipleStates = props => {
    const [state, dispatcher] = useReducer(myReducer, ['initial value']);
    console.log(state);

    // Three different state triggers
    const addHandler = () => {
        dispatcher({ type: 'ADD', payload: Math.round((Math.random() * 100 + 100)) });
    };
    const removeHandler = () => {
        dispatcher({ type: 'REMOVE' });
    };
    const clearHandler = () => {
        dispatcher({ type: 'CLEAR' });
    };

    return (
        <>
            <hr />
            <h2>useReducer use case</h2>
            <h3>Manage multiple states: modify an array</h3>
            <button onClick={addHandler}>[+] Add random value to array</button>
            <button style={{ margin: "0 2rem" }} onClick={removeHandler}>[-] Remove last value from array</button>
            <button onClick={clearHandler}>[x] Clear array</button>
            <p>Shopping cart array:</p>
            <p><b>{state.length === 0 && '(empty)'}{state.join(' - ')}</b></p>
        </>
    );
};

export default UseCaseMultipleStates;

Modify complex states, such as arrays or objects: login form

useReducer can be especially handy when dealing with multiple states and a complex state logic.

By handling a login form with this hook instead of multiple useState hooks we can appreciate how powerful this hook is.

Helper function for simulating a login API (thanks to Harry Wolff for this code):

export async function loginHelper({ username, password }) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            if (username === 'user' && password === 'password') {
                resolve();
            } else {
                reject();
            }
        }, 1000);
    });
}

Main component:

import { useReducer } from "react";
import { loginHelper } from "./loginHelper";

const myReducer = (prevState, action) => {
    switch (action.type) {
        case 'USERNAME':
            return {
                ...prevState,
                username: action.payload,
            };
        case 'PASSWORD':
            return {
                ...prevState,
                password: action.payload,
            };
        case 'LOGGED_IN':
            return {
                ...prevState,
                isLoggedIn: true,
            };
        case 'LOGGED_OUT':
            return {
                ...prevState,
                isLoggedIn: false,
                username: '',
                password: '',
            };
        case 'IS_LOADING':
            return {
                ...prevState,
                isLoading: true,
            };
        case 'IS_NOT_LOADING':
            return {
                ...prevState,
                isLoading: false,
            };
        case 'ERROR':
            return {
                ...prevState,
                isError: true,
                isLoading: false,
            };

        default:
            break;
    }
};

const initialState = {
    username: '',
    password: '',
    isLoggedIn: false,
    isLoading: false,
    isError: false,
};

const UseCaseComplexStates = props => {
    const [state, dispatcher] = useReducer(myReducer, initialState);

    const usernameHandler = e => {
        dispatcher({ type: 'USERNAME', payload: e.target.value });
    };

    const passwordHandler = e => {
        dispatcher({ type: 'PASSWORD', payload: e.target.value });
    };

    const logoutHandler = e => {
        dispatcher({ type: 'LOGGED_OUT' });
    };

    const submitHandler = async e => {
        e.preventDefault();

        // Check credentials (simulated)
        try {
            dispatcher({ type: 'IS_LOADING' });
            await loginHelper({ username: state.username, password: state.password });
            dispatcher({ type: 'IS_NOT_LOADING' });
            dispatcher({ type: 'LOGGED_IN' });
        } catch {
            dispatcher({ type: 'ERROR' });
            alert('? Incorrect username or password');
        }
    };

    return (
        <>
            <hr />
            <h2>useReducer use case</h2>
            <h3>Modify complex states, such as arrays or objects: login form</h3>
            <div style={{ maxWidth: '50%', backgroundColor: '#a8dadc', borderRadius: '1rem', padding: '2rem' }}>
                {state.isLoggedIn
                    ? <><p>Welcome!</p><button onClick={logoutHandler}>Log out!</button></>
                    : <form onSubmit={submitHandler}>
                        <div style={{ margin: '1rem 0' }}>
                            <label htmlFor="username">Username</label>
                            <input type="text" id="username" onChange={usernameHandler} value={state.username} style={{ margin: '0 1rem' }} placeholder='user' />
                        </div>
                        <div style={{ margin: '1rem 0' }}>
                            <label htmlFor="password">Password</label>
                            <input type="password" id="password" onChange={passwordHandler} value={state.password} style={{ margin: '0 1rem' }} placeholder='password' />
                        </div>
                        <div style={{ margin: '1rem 0' }}>
                            <button type="submit" disabled={state.isLoading}>{state.isLoading ? 'Logging you in...' : 'Log in'}</button>
                        </div>

                    </form>
                }
            </div>
        </>
    );
};

export default UseCaseComplexStates;

You can watch all these examples live here.

You can also take a look at the code in this repository.


This content originally appeared on DEV Community and was authored by Damian Demasi


Print Share Comment Cite Upload Translate Updates
APA

Damian Demasi | Sciencx (2021-09-16T22:48:16+00:00) 2 use cases of the useReducer ReactJS hook. Retrieved from https://www.scien.cx/2021/09/16/2-use-cases-of-the-usereducer-reactjs-hook/

MLA
" » 2 use cases of the useReducer ReactJS hook." Damian Demasi | Sciencx - Thursday September 16, 2021, https://www.scien.cx/2021/09/16/2-use-cases-of-the-usereducer-reactjs-hook/
HARVARD
Damian Demasi | Sciencx Thursday September 16, 2021 » 2 use cases of the useReducer ReactJS hook., viewed ,<https://www.scien.cx/2021/09/16/2-use-cases-of-the-usereducer-reactjs-hook/>
VANCOUVER
Damian Demasi | Sciencx - » 2 use cases of the useReducer ReactJS hook. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2021/09/16/2-use-cases-of-the-usereducer-reactjs-hook/
CHICAGO
" » 2 use cases of the useReducer ReactJS hook." Damian Demasi | Sciencx - Accessed . https://www.scien.cx/2021/09/16/2-use-cases-of-the-usereducer-reactjs-hook/
IEEE
" » 2 use cases of the useReducer ReactJS hook." Damian Demasi | Sciencx [Online]. Available: https://www.scien.cx/2021/09/16/2-use-cases-of-the-usereducer-reactjs-hook/. [Accessed: ]
rf:citation
» 2 use cases of the useReducer ReactJS hook | Damian Demasi | Sciencx | https://www.scien.cx/2021/09/16/2-use-cases-of-the-usereducer-reactjs-hook/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.