Inicio > Cursos > React > Estado Global: Zustand y Redux Toolkit
ReactReact AvanzadoLección 19 de 21

Estado Global: Zustand y Redux Toolkit

Context + useReducer funciona para estado moderado, pero en apps grandes con estado complejo (carrito de compras, auth, preferencias, datos cacheados) tiene problemas: cada cambio re-renderiza TODOS los consumidores del Context, y la lógica queda dispersa en múltiples reducers. Las librerías de estado global resuelven esto con re-renders selectivos y APIs más ergonómicas.

Zustand es la opción más popular por su simplicidad. Creas un "store" con create(), defines estado y acciones juntas, y los componentes se suscriben solo a las partes que necesitan — si cambia el carrito, solo se re-renderizan los componentes que usan el carrito. Redux Toolkit (RTK) es más estructura y convenciones: slices, actions, reducers inmutables con Immer. Úsalo en equipos grandes que necesitan predictabilidad estricta.

// --- ZUSTAND (minimalista, recomendado) ---
import { create } from "zustand";

const useStore = create((set, get) => ({
  // Estado
  items: [],
  total: 0,

  // Acciones (modifican el estado)
  addItem: (item) => set((state) => ({
    items: [...state.items, item],
    total: state.total + item.precio,
  })),

  removeItem: (id) => set((state) => {
    const item = state.items.find(i => i.id === id);
    return {
      items: state.items.filter(i => i.id !== id),
      total: state.total - (item?.precio || 0),
    };
  }),

  clearCart: () => set({ items: [], total: 0 }),
}));

// Componente — solo se re-renderiza si "total" cambia
function CartTotal() {
  const total = useStore((s) => s.total);
  return <p>Total: ${total}</p>;
}

// Componente — solo se re-renderiza si "items" cambia
function CartItems() {
  const items = useStore((s) => s.items);
  const removeItem = useStore((s) => s.removeItem);
  return items.map(i => (
    <div key={i.id}>
      {i.nombre} - ${i.precio}
      <button onClick={() => removeItem(i.id)}>X</button>
    </div>
  ));
}

// --- REDUX TOOLKIT (más estructura) ---
import { configureStore, createSlice } from "@reduxjs/toolkit";

const cartSlice = createSlice({
  name: "cart",
  initialState: { items: [], total: 0 },
  reducers: {
    addItem: (state, action) => {
      state.items.push(action.payload); // Immer permite "mutar"
      state.total += action.payload.precio;
    },
  },
});

const store = configureStore({ reducer: { cart: cartSlice.reducer } });
// Componente: useSelector(s => s.cart.total), useDispatch()
Consejo🎯 Zustand para proyectos pequeños/medianos (90% de los casos). Redux Toolkit para equipos grandes con convenciones estrictas. Ambos permiten re-renders selectivos que Context no ofrece.
← Testing de ComponentesReact Server Components (RSC) →

Practica esta lección

Resuelve los ejercicios del curso de React en la app, gratis y con corrección automática.

Empezar a practicar