Zustand es una librería ligera y flexible para gestionar el estado en aplicaciones React. Ofrece una API simple pero poderosa, eliminando la necesidad de acciones, reducers y middlewares complejos.
Es ideal para manejar estados pequeños o grandes de forma rápida, eficiente y escalable, y representa una alternativa sencilla a opciones más complejas como Redux o Context API.
immer para manejar inmutabilidad.localStorage o logs.Instala Zustand usando npm o yarn:
npm install zustand
# o
yarn add zustand Para configurar Zustand en nuestro proyecto, es necesario definir un store.
Podemos crear tantos stores como necesitemos, ya que cada uno puede estar diseñado para manejar estados específicos dentro de nuestra aplicación.
Es buena práctica organizar los stores en una carpeta dedicada llamada store.
Dentro de esta carpeta, crea un archivo como store.jsx o store.tsx, dependiendo de si usas JavaScript o TypeScript.
Esta estructura facilita la organización y escalabilidad del proyecto.
En Zustand, defines el estado y las acciones en un archivo central. Aquí un ejemplo básico:
// store.js
import { create } from 'zustand';
const useStore = create((set) => ({
count: 0, // Estado inicial del contador
increment: () => set((state) => ({ count: state.count + 1 })),
decrement: () => set((state) => ({ count: state.count - 1 })),
})
);
export default useStore; create: Es una función que Zustand exporta para crear tu store (almacén).
createEl propósito principal de la función create es inicializar el estado global y definir las acciones (funciones que cambian ese estado).
Es similar a inicializar un useState, pero con alcance global.
import { create } from 'zustand'; const useStore = create((set) => ({
count: 0, // Estado inicial del contador
increment: () => set((state) => ({ count: state.count + 1 })), // Incrementar el contador
decrement: () => set((state) => ({ count: state.count - 1 })), // Decrementar el contador
})
); A continuación, describiremos algunos puntos clave que te ayudarán a comprender mejor el funcionamiento de Zustand:
useStore: Es un hook personalizado que Zustand genera para ti.
Permite acceder al estado global y las acciones en cualquier componente de React.set: Función de Zustand para actualizar el estado global (similar a setState en React).count: 0: Estado inicial del contador.increment: Es una Función que usa la función set para aumentar el valor de count en 1.decrement: Es una Función que usa la función set para disminuir el valor de count en 1.(state): Función que recibe el estado actual del store (a través de state, en este caso, un objeto que contiene count).state.count: Es un acceso al valor actual de la propiedad count dentro del estado.{ count: state.count + 1 } actualiza count aumentando en 1.{ count: state.count - 1 } actualiza count disminuyéndolo en 1.{ count: state.count + 1 } y { count: state.count - 1 }: Son los objetos que devuelven el nuevo estado actualizado de count.+ 1: Suma 1 al valor actual de count.{ count: ... }: Devuelve un nuevo objeto con el valor actualizado de count.set(...): es crucial porque le dice a Zustand que debe aplicar el cambio en el estado global.
Dentro de set(), pasas una función que toma el estado actual (state) y devuelve el nuevo estado, lo cual es fundamental en Zustand para actualizar el store de manera reactiva.En Zustand, set es una función que se usa para actualizar el estado.
Se pasa como argumento a una función que recibe el estado actual (denominado state).
Dentro de esa función, modificamos el estado y devolvemos un nuevo objeto con los valores actualizados.
Por ejemplo, set((state) => ({ count: state.count + 1 })) actualiza count incrementándolo en 1.
La función set permite que las modificaciones sean aplicadas globalmente.
Una vez que hemos definido nuestro store, podemos utilizarlo en cualquier página o componente de nuestra aplicación. Para ello, simplemente debemos importarlo y extraer los atributos o métodos necesarios.
useStore para interactuar con el estado y las funciones definidas en el store.Esto permite aprovechar el estado global de manera sencilla y eficiente dentro de tus componentes.
// App.js
// Importando el store useStore
import useStore from './store/store';
const Counter = () => {
const count = useStore((state) => state.count);
const increment = useStore((state) => state.increment);
const decrement = useStore((state) => state.decrement);
return (
<div>
<h1>Count: {count}</h1>
<button onClick={increment}>Increment</button>
<button onClick={decrement}>Decrement</button>
</div>
);
};
export default Counter; useStore dentro de componentes funcionales o hooks personalizados.set debe retornar un nuevo estado, no mutar el existente.Úsalo para manejar estados como el tema claro/oscuro o el idioma:
const useThemeStore = create((set) => ({
theme: 'light',
toggleTheme: () =>
set((state) => ({ theme: state.theme === 'light' ? 'dark' : 'light' })),
})); Gestión de un carrito de compras:
const useCartStore = create((set) => ({
cart: [],
addToCart: (item) => set((state) => ({ cart: [...state.cart, item] })),
removeFromCart: (id) =>
set((state) => ({ cart: state.cart.filter((item) => item.id !== id) })),
})); Persistir datos en localStorage usando un middleware:
import { create } from 'zustand';
import { persist } from 'zustand/middleware';
const useStore = create(
persist(
(set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
}),
{ name: 'counter-storage' } // Clave en localStorage
)
); Manejo de usuario autenticado:
const useAuthStore = create((set) => ({
user: null,
login: (userData) => set(() => ({ user: userData })),
logout: () => set(() => ({ user: null })),
})); Archivo store.js:
import { create } from 'zustand';
const useStore = create((set) => ({
count: 0,
theme: 'light',
increment: () => set((state) => ({ count: state.count + 1 })),
toggleTheme: () =>
set((state) => ({ theme: state.theme === 'light' ? 'dark' : 'light' })),
}));
export default useStore; Archivo App.js:
import useStore from './store/store';
const App = () => {
const count = useStore((state) => state.count);
const theme = useStore((state) => state.theme);
const increment = useStore((state) => state.increment);
const toggleTheme = useStore((state) => state.toggleTheme);
return (
<div style={{ backgroundColor: theme === 'light' ? '#fff' : '#333', color: theme === 'light' ? '#000' : '#fff' }}>
<h1>Count: {count}</h1>
<button onClick={increment}>Increment</button>
<button onClick={toggleTheme}>Toggle Theme</button>
</div>
);
};
export default App; | Función | Descripción |
|---|---|
create | Crea el “store” con estado y acciones. |
set | Permite actualizar el estado global. |
useStore | Hook personalizado que accede al estado o acciones del “store”. |
(state) => ... | Recibe el estado actual y retorna un nuevo estado, respetando la inmutabilidad. |