Script Valley
React.js: Complete Course
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.

Combining Zustand and React Query in a real app โ€” State Management with Zustand and React Query โ€” React.js: Complete Course โ€” Script Valley โ€” Script Valley