- Selective subscription:
// Not recommended: Subscribes to entire store, causing re-renders on any state change
const { count, user } = useStore();
// Recommended: Subscribe only to needed state parts
const count = useStore((state) => state.count);
const user = useStore((state) => state.user);
- Using shallow comparison (for complex objects):
import { create } from 'zustand';
import { shallow } from 'zustand/shallow';
// Subscribe to multiple states with shallow comparison
const { count, user } = useStore(
(state) => ({ count: state.count, user: state.user }),
shallow // Only re-renders when count or user actually changes
);
- State splitting:
// Split into multiple stores by functionality
// userStore.js
const useUserStore = create((set) => ({
user: null,
setUser: (user) => set({ user })
}));
// counterStore.js
const useCounterStore = create((set) => ({
count: 0,
increment: () => set((state) => ({ count: state.count + 1 }))
}));
- Using get to access current state (avoid closure traps):
const useStore = create((set, get) => ({
count: 0,
// Recommended: Use get to get latest state
increment: () => set((state) => ({ count: state.count + 1 })),
// Can also use get
incrementAsync: async () => {
await someAsyncOperation();
set({ count: get().count + 1 });
}
}));
- Batch updates:
// Zustand automatically batches multiple set calls
const updateMultiple = () => {
set({ count: 1 });
set({ user: { name: 'John' } });
// Only triggers one re-render
};
- Avoid creating new functions during component render:
// Not recommended: Creates new function on every render
const incrementBy = (value) => useStore.getState().incrementBy(value);
// Recommended: Define methods in the store
// In store:
incrementBy: (value) => set((state) => ({ count: state.count + value }))
// In component:
const incrementBy = useStore((state) => state.incrementBy);
Key points:
- Selective subscription is the core of Zustand performance optimization
- Shallow comparison can optimize subscription to complex objects
- State splitting reduces unnecessary re-renders
- Proper use of get avoids closure traps
- Zustand automatically handles batch updates