TUTORIALS |
JUNE 05, 2024 |
By Spareek |
8 MIN READ
Modern State Management with Zustand
Redux defined a generation of React architecture, but its ceremony and boilerplate have become overwhelming. Context API is built-in but inherently triggers cascading re-renders across all consumers whenever any slice of state changes. The answer lies somewhere in the middle: Zustand.
Zustand is a tiny, fast, and scalable state management library. It uses an incredibly small footprint to create an explicit global store that hooks into React safely. It’s un-opinionated, yet structurally sound, allowing for transient state updates without mounting context providers.
The Selector Optimization Pattern
The magic of Zustand lies in its subscription model. Instead of subscribing a component to the entire store, components define a selector function to request only the specific slice of state they require.
If other fields in the store change, React will skip rendering the component because the selected value remains referentially equal. This solves the classic React Context re-render problem without wrapping components in React.memo or splitting states across multiple providers.
State Management Comparison
| Library |
Boilerplate |
Re-render Control |
Bundle Size |
| React Context |
Minimal |
Poor (All consumers re-render) |
Built-in (0 KB) |
| Redux Toolkit |
High (Actions, Reducers, Slices) |
Excellent (via selectors) |
~30 KB |
| Zustand |
Minimal (Just hook calls) |
Excellent (via selectors) |
~1.5 KB |
zustand-store.ts
import create from 'zustand';
import persist from 'zustand/middleware';
interface AppState
theme: 'light' | 'dark';
toggleTheme: () => void;
userToken: string | null;
setToken: (token: string) => void;
export const useAppStore = create()(
persist(
(set) => ({
theme: 'dark',
toggleTheme: () => set((state) => (
theme: state.theme === 'dark' ? 'light' : 'dark'
)),
userToken: null,
setToken: (token) => set( userToken: token ),
}),
name: 'app-storage'
)
);
Advanced Middleware and Devtools
Because Zustand stores are external JavaScript closures, it is easy to wrap their state updates in custom middleware. In the example code above, we utilize the built-in persist middleware to automatically save store values to localStorage and sync state back on reload.
Zustand also provides developer tools, DevTools logging, and action tracking out-of-the-box. For applications heavily reliant on rapidly shifting states—like live dashboards or real-time web applications—Zustand bypasses typical Render-Cycle traps. You can update state outside of React entirely and subscribe components only to the slice of state they care about.