State Management Differences with PWA Kit

PWA Kit’s state management is React Query-centric, treating the API as the source of truth with sophisticated caching. Storefront Next takes a server-first approach where loaders provide data and client state is minimal and feature-specific. The shift eliminates the need for a dedicated server state library, simplifying the mental model while enabling better streaming and Suspense integration.

Key Differences 

AspectPWA KitStorefront Next
Primary ApproachReact Query for server stateReact Router loaders
State LibraryReact Query + ContextReact Router Context + React State
CachingReact Query in-memory cacheRouter revalidation
Server StateManaged by React QueryManaged by React Router
PersistencelocalStorageCookies
ArchitectureCentralized (React Query)Decentralized

Server State Management 

PWA Kit uses React Query for all server state:

1// PWA Kit: Data fetched in component via hooks
2const ProductPage = ({ productId }) => {
3  const { data, isLoading } = useProduct({ parameters: { id: productId } });
4  // Component handles loading state
5};

Storefront Next uses loaders for server state:

1// Storefront Next: Data fetched before component renders
2export function loader({ params, context }) {
3  return { product: fetchProduct(params.productId) };
4}
5
6const ProductPage = ({ loaderData }) => {
7  const product = use(loaderData.product); // Suspends if not ready
8};

Key Similarities 

  1. React Context for distribution: Both use Context to make state available to components.
  2. Provider pattern: Both wrap the app in provider components.
  3. Hooks for consumption: Both expose custom hooks (useAuth, useBasket, etc.).
  4. Persistence considerations: Both handle localStorage/cookies for persistence.
  5. SSR awareness: Both handle server vs client rendering differences.

Storefront Conversion Considerations 

Keep these considerations in mind when converting your storefront from PWA Kit to Storefront Next.

  • React Query to Loaders

    • Move data fetching from component hooks to route loaders.
    • Replace isLoading checks with Suspense boundaries.
    • Remove React Query configuration and providers.
  • Context Simplification

    • Simplify contexts to just hold values (no complex logic).
    • Move complex state to Zustand if needed.
    • Use middleware for initialization instead of provider effects.
  • State Persistence

    • Migrate localStorage usage to cookies for SSR compatibility.
    • Use middleware to read persisted state during request processing.
  • Derived State

    • Move derived calculations from hooks to selectors (Zustand) or loaders.
    • Use useMemo sparingly; prefer computed values in state stores.