JAVASCRIPT

React Hook: useReducer for Complex State Logic

Leverage `useReducer` in React for managing complex state transitions, providing a robust and scalable alternative to `useState` for intricate component state.

import { useReducer } from 'react';

const initialState = { count: 0, loading: false, error: null };

function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return { ...state, count: state.count + 1 };
    case 'decrement':
      return { ...state, count: state.count - 1 };
    case 'reset':
      return initialState;
    case 'startLoading':
      return { ...state, loading: true, error: null };
    case 'stopLoading':
      return { ...state, loading: false };
    case 'setError':
      return { ...state, loading: false, error: action.payload };
    default:
      throw new Error();
  }
}

// How to use it:
/*
function ComplexCounter() {
  const [state, dispatch] = useReducer(reducer, initialState);

  const fetchData = async () => {
    dispatch({ type: 'startLoading' });
    try {
      // Simulate API call
      await new Promise(resolve => setTimeout(resolve, 1000));
      if (Math.random() > 0.8) throw new Error('Failed to fetch!');
      dispatch({ type: 'stopLoading' });
    } catch (err) {
      dispatch({ type: 'setError', payload: err.message });
    }
  };

  return (
    <div>
      <h1>Count: {state.count}</h1>
      {state.loading && <p>Loading...</p>}
      {state.error && <p style={{ color: 'red' }}>Error: {state.error}</p>}
      <button onClick={() => dispatch({ type: 'increment' })} disabled={state.loading}>+</button>
      <button onClick={() => dispatch({ type: 'decrement' })} disabled={state.loading}>-</button>
      <button onClick={() => dispatch({ type: 'reset' })} disabled={state.loading}>Reset</button>
      <button onClick={fetchData} disabled={state.loading}>Fetch Data</button>
    </div>
  );
}
*/
How it works: The `useReducer` hook is an alternative to `useState` for managing more complex state logic that involves multiple sub-values or where the next state depends on the previous one. It takes a `reducer` function (similar to Redux reducers) and an `initialState`. It returns the current state and a `dispatch` function. The `dispatch` function is used to send 'actions' to the reducer, which then computes and returns the new state, triggering a re-render. This pattern centralizes state updates, making them predictable and testable.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs