You might have heard of Redux, a popular library for managing your app's state. But Redux can be quite complex and verbose, which is where Zustand comes in as a simpler alternative.
What is Zustand?
Zustand is a state management library for React applications. It's like Redux but with a much easier and more intuitive API. With Zustand, you can handle your app's state in a more organized and scalable way without drowning in boilerplate code.
Creating a Store
In Zustand, creating a store is a breeze. You can define your store using the create function. Here's a simple example:
import { create } from "zustand";
const store = (set, get) => ({
value: 0,
inc: (p) => {
set((s) => ({ ...s, value: s.value + p }));
},
dec: () => set((s) => ({ ...s, value: get().value + 1 })),
});
export const useCounter = create(store);Here, set is similar to setState, and p is like the payload in Redux. However, in Zustand, the payload goes through a reducer, not directly to set. You can also pass additional parameters to set to control its behavior.
Fetching Data from the Store
Fetching data from the Zustand store is simple and flexible. You can pick exactly what you need:
const { value, inc } = useCounter(); // Fetching all
// or
const inc = useCounter((state) => state.inc); // Fetching specific
// or
const [value, inc] = useCounter((state) => [state.value, state.inc]); // Array pick
// or
const { value, inc } = useCounter((state) => ({ value: state.value, inc: state.inc })); // Object pickZustand/Shallow
If you want to optimize performance and prevent unnecessary re-renders, you can use zustand/shallow like this:
import { shallow } from 'zustand/shallow';
import { useStore } from './store';
function MyComponent() {
const { name, age } = useStore(state => ({ name: state.name, age: state.age }), shallow);
// Do something with name and age...
return <div>{name} is {age} years old.</div>;
}Using Zustand Outside Components
Zustand isn't just for use within React components; you can use it in utility functions or libraries too:
// Get the current state
const state = useStore.getState();
// Call the increment method
useStore.getState().inc();
// or
state.inc();Subscribing to State Changes
You can subscribe to state changes with the subscribe method. It calls a callback function whenever the state changes:
import { create } from "zustand";
const store = (set) => ({
value: 0,
inc: (p) => {
set((s) => ({ ...s, value: s.value + p }));
},
});
export const useCounter = create(store);
// Subscribe to changes
useCounter.subscribe(
(state) => console.log("New state:", state),
(state) => state.value === 2 // Optional selector function to limit updates
);Middleware - Supercharge Zustand
Zustand comes with several middleware options to enhance its functionality.
Devtools - Redux Toolkit for Zustand
You can integrate the Redux DevTools with Zustand by adding the devtools middleware:
import create from 'zustand';
import { devtools } from 'zustand/middleware';
const store = (set) => ({
value: 0,
value2: 5,
inc: (p) => {
set((s) => ({ ...s, value: s.value + p }), false, 'inc');
},
});
// Just wrap the store
export const useCounter = create(devtools(store));Persist - Store on Local Storage
To persist your Zustand store on the user's local storage, use the persist middleware:
import create from "zustand";
import { persist } from "zustand/middleware";
const store = (set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 })),
});
export const useCounter = create(persist(store), { name: "counter" });This ensures that your app's state survives page refreshes.
Immer - Simplify State Updates
To simplify state updates, you can use the immer middleware with Zustand:
import create from 'zustand';
import { immer } from 'zustand/middleware';
const store = (set) => ({
value: 0,
inc: (p) => {
set((state) => { state.value += p; });
},
});
// Just wrap the store
export const useCounter = create(immer(store));This makes updating your state even easier.
In summary, Zustand is a fantastic alternative to Redux for managing state in your React applications. It's simple, flexible, and offers various middleware options to supercharge your app's state management. Give it a try in your next project and experience the difference!
