Manejo del estado global en React más allá de Context: Redux, Zustand y alternativas

Tiempo de lectura: 3 minutos

Cuando una aplicación crece, manejar el estado solo con useState o Context puede volverse complicado. Los datos que se comparten entre muchos componentes, como la información del usuario, configuraciones o listas de productos, necesitan un enfoque más robusto: el estado global.

Color naranja, estado global en react - pexels

En este tutorial descubrirás cómo manejar el estado global en React usando herramientas más allá de Context, cuándo utilizarlas y cómo elegir la mejor opción para tu proyecto.

Por qué Context no siempre es suficiente

Aunque Context es excelente para compartir datos entre componentes, tiene algunas limitaciones:

  • Cada cambio en el Provider provoca un re-render de todos los componentes que consumen ese contexto.
  • Puede ser difícil manejar estados complejos con muchas propiedades o lógica.
  • No incluye herramientas avanzadas como middleware, persistencia o devtools.

Cuando la aplicación crece, es recomendable usar un gestor de estado más especializado.

Alternativas populares al Context

1. Redux

Redux es una de las librerías más conocidas para manejar estado global en React. Sus características principales:

  • Estado centralizado en un store único.
  • Cambios de estado mediante acciones y reducers.
  • Middleware para manejar efectos secundarios, logging y más.
  • Integración con DevTools para depuración.

Ejemplo básico con Redux Toolkit

import { configureStore, createSlice } from "@reduxjs/toolkit";

const usuarioSlice = createSlice({
  name: "usuario",
  initialState: { nombre: "" },
  reducers: {
    setNombre: (state, action) => {
      state.nombre = action.payload;
    },
  },
});

export const { setNombre } = usuarioSlice.actions;

const store = configureStore({
  reducer: { usuario: usuarioSlice.reducer },
});

export default store;

Uso en un componente:

import { useSelector, useDispatch } from "react-redux";
import { setNombre } from "./store";

function Perfil() {
  const nombre = useSelector((state) => state.usuario.nombre);
  const dispatch = useDispatch();

  return (
    <div>
      <p>Nombre: {nombre}</p>
      <button onClick={() => dispatch(setNombre("Ismael"))}>
        Cambiar nombre
      </button>
    </div>
  );
}

Redux es ideal para aplicaciones grandes y complejas.

2. Zustand

Zustand es una alternativa ligera y moderna para manejar estado global.

  • No requiere boilerplate pesado.
  • Fácil de usar y combinar con Hooks.
  • Permite suscripciones a partes específicas del estado para evitar renders innecesarios.

Ejemplo básico:

import create from "zustand";

const useStore = create((set) => ({
  contador: 0,
  incrementar: () => set((state) => ({ contador: state.contador + 1 })),
}));

function Contador() {
  const { contador, incrementar } = useStore();
  return (
    <div>
      <p>{contador}</p>
      <button onClick={incrementar}>Sumar</button>
    </div>
  );
}

Zustand es excelente para proyectos medianos o cuando quieres simplicidad sin sacrificar funcionalidad.

3. Recoil

Recoil es una librería creada por Facebook que permite manejar estado global de forma muy reactiva y modular.

  • Los atoms son unidades de estado que se pueden compartir entre componentes.
  • Los selectors permiten derivar datos o aplicar lógica compleja.
  • Se integra naturalmente con React y soporta renderizado selectivo.

4. Jotai

Jotai es otra librería minimalista para estado global.

  • Basada en átomos de estado, similar a Recoil.
  • Ligera, simple y eficiente.
  • Ideal para aplicaciones pequeñas o medianas que buscan simplicidad.

Cómo elegir la herramienta adecuada

  • Context + useReducer: para estados simples o moderados.
  • Redux: cuando la aplicación es grande, con lógica compleja, middleware o necesidad de DevTools.
  • Zustand o Jotai: proyectos medianos que buscan simplicidad y eficiencia.
  • Recoil: cuando se necesita un manejo muy modular del estado y derivaciones complejas.

Buenas prácticas al manejar estado global

  • Mantén el estado lo más organizado posible y evita mezclar responsabilidades.
  • Divide el estado en “slices” o unidades lógicas.
  • Evita actualizar el estado global para datos muy locales o temporales.
  • Aprovecha la memoización y suscripciones selectivas para reducir renders innecesarios.

Deja un comentario