State Management with Zustand and React QueryLesson 6.5
Combining Zustand and React Query in a real app
separation of concerns, server state in React Query, UI state in Zustand, derived state, avoiding duplication, real app architecture, devtools setup
Combining Zustand + React Query
The best practice: use React Query exclusively for server data (API responses), and Zustand for client/UI state (filters, selected items, modal state). Never put server data into Zustand — you lose caching, deduplication, and revalidation.
Example Architecture
// React Query — server state
const { data: products } = useQuery({
queryKey: ['products', { category: selectedCategory }],
queryFn: () => fetchProducts(selectedCategory),
});
// Zustand — UI/client state
const useUIStore = create((set) => ({
selectedCategory: 'all',
viewMode: 'grid',
setCategory: (cat) => set({ selectedCategory: cat }),
setViewMode: (mode) => set({ viewMode: mode }),
}));
function ProductsPage() {
const { selectedCategory, viewMode, setCategory } = useUIStore();
const { data: products, isLoading } = useQuery({
queryKey: ['products', selectedCategory],
queryFn: () => fetchProducts(selectedCategory),
});
return (
<div>
<CategoryFilter value={selectedCategory} onChange={setCategory} />
{isLoading ? <Spinner /> : <ProductGrid items={products} mode={viewMode} />}
</div>
);
}Install React Query DevTools in development to inspect cache state. Zustand's devtools middleware integrates with Redux DevTools. Both tools together give you full visibility into your app's state in development.
