Open In App

How to handle complex state logic with useReducer?

Last Updated : 22 Feb, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

useReducer hook is a powerful alternative to useState when you have complex state logic that involves multiple sub-values or when the next state depends on the previous one. It’s particularly useful when the state logic involves more than just simple state updates. Handling complex state logic with useReducer in React involves defining a reducer function that manages state transitions based on dispatched actions.

Handling complex state logic with useReducer:

  • Understanding useReducer: useReducer is a React hook used for managing state in functional components. It’s an alternative to useState, particularly useful when state logic becomes complex.
  • Defining the Reducer Function: You start by defining a reducer function. This function takes two arguments i.e. the current state and an action. It then returns the new state based on the action type.
  • Dispatching Actions: Actions are objects that describe the type of state change you want to make. When you want to update state, you dispatch an action to the reducer.
  • Handling Complex Logic: Complex state logic involves managing multiple state changes based on different conditions or inputs. The reducer function encapsulates this logic, making it easier to manage and debug.
  • State Transition: The reducer function calculates the new state based on the current state and the action dispatched. It returns this new state, which then becomes the current state.
  • Updating Components: When the state changes, React re-renders the components that depend on that state, ensuring your UI stays in sync with the data.

Example: Below is an example of handling complex state logic with useReducer.

Javascript




import React, {
    useReducer
}
    from 'react';
 
// Define initial state
const initialState = {
    count: 0,
    isEven: false
};
 
// Define action types
const actionTypes = {
    INCREMENT: 'INCREMENT',
    DECREMENT: 'DECREMENT',
    RESET: 'RESET'
};
 
// Reducer function
const reducer = (state, action) => {
    switch (action.type) {
        case actionTypes.INCREMENT:
            return {
                ...state,
                count: state.count + 1,
                isEven: (state.count + 1) % 2 === 0
            };
        case actionTypes.DECREMENT:
            return {
                ...state,
                count: state.count - 1,
                isEven: (state.count - 1) % 2 === 0
            };
        case actionTypes.RESET:
            return initialState;
        default:
            return state;
    }
};
 
// Component
const ComplexStateComponent = () => {
    const [state, dispatch] = useReducer(reducer,
        initialState);
 
    return (
        <div>
            <p>Count: {state.count}</p>
            <p>Is Even: {state.isEven ? 'Yes' : 'No'}</p>
            <button onClick={() =>
                dispatch({ type: actionTypes.INCREMENT })}>
                Increment
            </button>
            <button onClick={() =>
                dispatch({ type: actionTypes.DECREMENT })}>
                Decrement
            </button>
            <button onClick={() =>
                dispatch({ type: actionTypes.RESET })}>
                Reset
            </button>
        </div>
    );
};
 
export default ComplexStateComponent;


Output:

gfg42

Ouput



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads