useReducer

#atom

Managing complex state with the reducer pattern in React

Core Idea: useReducer is a React Hook that manages component state through a reducer function, allowing complex state logic to be separated from the component rendering logic.

Key Elements

Key Principles

When to Use useReducer

Implementation Steps

  1. Define a reducer function that takes (state, action) and returns new state
  2. Initialize with const [state, dispatch] = useReducer(reducer, initialState)
  3. Access current state from the first returned value
  4. Trigger state changes by calling dispatch(action)

Code Example

Basic Shopping List Implementation

import { useReducer } from 'react';

// Define the reducer function
function shoppingListReducer(state, action) {
  switch (action.type) {
    case 'ADD_ITEM':
      return [...state, {
        id: Date.now(),
        name: action.name,
        completed: false
      }];
    case 'TOGGLE_ITEM':
      return state.map(item => {
        if (item.id === action.id) {
          return { ...item, completed: !item.completed };
        }
        return item;
      });
    case 'REMOVE_ITEM':
      return state.filter(item => item.id !== action.id);
    default:
      throw new Error(`Unknown action type: ${action.type}`);
  }
}

function ShoppingList() {
  // Initialize useReducer with the reducer and initial state
  const [items, dispatch] = useReducer(shoppingListReducer, []);
  const [newItemName, setNewItemName] = useState('');
  
  const handleAddItem = () => {
    if (newItemName.trim()) {
      dispatch({ type: 'ADD_ITEM', name: newItemName });
      setNewItemName('');
    }
  };
  
  return (
    <div>
      <h2>Shopping List</h2>
      <input 
        value={newItemName}
        onChange={(e) => setNewItemName(e.target.value)}
      />
      <button onClick={handleAddItem}>Add Item</button>
      
      <ul>
        {items.map(item => (
          <li key={item.id}>
            <span 
              style={{ textDecoration: item.completed ? 'line-through' : 'none' }}
              onClick={() => dispatch({ type: 'TOGGLE_ITEM', id: item.id })}
            >
              {item.name}
            </span>
            <button onClick={() => dispatch({ type: 'REMOVE_ITEM', id: item.id })}>
              Delete
            </button>
          </li>
        ))}
      </ul>
    </div>
  );
}

Benefits and Considerations

Benefits

Considerations

Additional Connections

References

  1. React Documentation: https://react.dev/reference/react/useReducer
  2. Redux Documentation (for conceptual understanding): https://redux.js.org/tutorials/fundamentals/part-2-concepts-data-flow

#react #hooks #state-management #reducer #functional-programming


Sources: