Cuando tu componente React tiene un estado complejo, usar useState puede volverse caótico.

El truco

ANTES (usando useState):

const MiComponente = () => {
  const [estado, setEstado] = useState({
    contador: 0,
    texto: '',
    usuario: null
  });

  const incrementar = () => setEstado({ ...estado, contador: estado.contador + 1 });
  const actualizarTexto = (nuevoTexto) => setEstado({ ...estado, texto: nuevoTexto });
  const establecerUsuario = (nuevoUsuario) => setEstado({ ...estado, usuario: nuevoUsuario });

  // Render y otros métodos...
};

DESPUÉS (usando useReducer):

const initialState = {
  contador: 0,
  texto: '',
  usuario: null
};

const reducer = (state, action) => {
  switch (action.type) {
    case 'INCREMENTAR':
      return { ...state, contador: state.contador + 1 };
    case 'ACTUALIZAR_TEXTO':
      return { ...state, texto: action.payload };
    case 'ESTABLECER_USUARIO':
      return { ...state, usuario: action.payload };
    default:
      return state;
  }
};

const MiComponente = () => {
  const [estado, dispatch] = useReducer(reducer, initialState);

  const incrementar = () => dispatch({ type: 'INCREMENTAR' });
  const actualizarTexto = (nuevoTexto) => dispatch({ type: 'ACTUALIZAR_TEXTO', payload: nuevoTexto });
  const establecerUsuario = (nuevoUsuario) => dispatch({ type: 'ESTABLECER_USUARIO', payload: nuevoUsuario });

  // Render y otros métodos...
};

useReducer te ayuda a gestionar estados complejos con una lógica clara, evitando la repetición en cada update del estado. Define acciones y deja que el reducer decida cómo modificar el estado, manteniendo tu código organizado y manejable.

Conclusión: Si tu estado es más que un simple contador, usa useReducer para un manejo más claro y efectivo.