DevPath · Aprende a programar ESPTEN

useReducer y Context

useReducer: estado con transiciones claras

¿Cuándo useReducer en lugar de useState?

useState es perfecto para valores simples e independientes. Pero cuando el estado es complejo (varios campos relacionados) o las actualizaciones siguen transiciones claras (varias formas distintas de cambiarlo), repartir la lógica entre muchos setX se vuelve frágil y difícil de seguir.

useReducer concentra toda esa lógica en una sola función: el reducer.

El reducer: (state, action) => nextState

Un reducer es una función pura que recibe el estado actual y una acción, y devuelve el siguiente estado. No muta el estado: construye y devuelve uno nuevo.

function reducer(state, action) {
  switch (action.type) {
    case "incrementar":
      return { cuenta: state.cuenta + 1 };
    case "decrementar":
      return { cuenta: state.cuenta - 1 };
    default:
      return state;
  }
}

dispatch: enviar acciones

En el componente, useReducer(reducer, estadoInicial) devuelve un par: el estado actual y una función dispatch. Para cambiar el estado, "despachas" una acción describiendo qué ha pasado:

function Contador() {
  const [state, dispatch] = useReducer(reducer, { cuenta: 0 });

  return (
    <div>
      <p>Cuenta: {state.cuenta}</p>
      <button onClick={() => dispatch({ type: "incrementar" })}>+1</button>
      <button onClick={() => dispatch({ type: "decrementar" })}>-1</button>
    </div>
  );
}

La acción suele ser un objeto con una propiedad type (y, si hace falta, datos extra como payload). La ventaja: la lógica vive en un solo sitio, es fácil de leer y de probar, y los componentes solo dicen qué ocurrió, no cómo cambia el estado.

En los ejercicios, useReducer ya está disponible: úsalo directamente, sin importarlo.

Pon esto en práctica

DevPath es un curso práctico: aquí lees la teoría; en la app la pones en práctica con ejercicios que se ejecutan de verdad, sin conexión.

Empezar gratis en la app →
Context API: evitar el prop drilling →