GitHub

E-commerce Dashboard

A full-featured admin panel using TanStack Query for server state and TanStack Table for data rendering with real-time updates.

01

Principle

Dashboard architecture separates data fetching from UI rendering. TanStack Query manages all server state — metrics, orders, inventory — while TanStack Table handles display logic. This eliminates the need for manual caching and pagination state.

lightbulb

Centralize all query keys in a factory file. This prevents key collisions and makes invalidation predictable across your entire dashboard.

02

Rules

  • check_circle
    Query Key FactoryUse hierarchical array keys: ["orders", "list", filters] for precise cache control.
  • check_circle
    Separate Data LayersKeep fetch functions outside components. Services folder → custom hooks → UI.
  • check_circle
    Prefetch on HoverPrefetch linked records on hover to make navigation feel instant.
  • check_circle
    Optimistic UIApply mutations optimistically and roll back on error for a snappy user experience.
03

Pattern

hooks/queries/useDashboardMetrics.ts
import { useQuery } from '@tanstack/react-query';
import { dashboardKeys } from '@/lib/query-keys';

export const useDashboardMetrics = (range: DateRange) => {
  return useQuery({
    queryKey: dashboardKeys.metrics(range),
    queryFn: () => fetchMetrics(range),
    staleTime: 1000 * 60 * 5, // 5 minutes
    placeholderData: (prev) => prev,
  });
};
04

Implementation

info

Version Compatibility

Requires React 19+ and the latest stable versions of all dependencies shown.

In Next.js App Router, prefetch dashboard data in the server component and pass it to the client via HydrationBoundary for instant initial render.

app/dashboard/page.tsx
import { HydrationBoundary, dehydrate } from '@tanstack/react-query';
import { getQueryClient } from '@/lib/get-query-client';

export default async function DashboardPage() {
  const qc = getQueryClient();
  await qc.prefetchQuery({
    queryKey: dashboardKeys.metrics('7d'),
    queryFn: () => fetchMetrics('7d'),
  });
  return (
    <HydrationBoundary state={dehydrate(qc)}>
      <DashboardClient />
    </HydrationBoundary>
  );
}
menu_book
React Patterns

Helping developers build robust React applications since 2025.

© 2025 React Patterns Cookbook. Built with ❤️ for the community.
react-principles