CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-tanstack--react-query-persist-client

React bindings to work with persisters in TanStack/react-query

Pending
Overview
Eval results
Files

react-provider.mddocs/

React Provider

The PersistQueryClientProvider component provides React-specific persistence capabilities by wrapping the standard QueryClientProvider with automatic cache restoration and persistence subscription.

Capabilities

PersistQueryClientProvider Component

Main React provider component that manages the complete persistence lifecycle for React Query cache.

/**
 * React provider component that wraps QueryClientProvider to add persistence capabilities
 * Automatically restores cache on mount and subscribes to changes for continuous persistence
 * @param props - Component props including persist options and callbacks
 * @returns JSX element providing persistence context
 */
function PersistQueryClientProvider(props: PersistQueryClientProviderProps): React.JSX.Element;

interface PersistQueryClientProviderProps extends QueryClientProviderProps {
  /** Persistence configuration options (queryClient is automatically provided) */
  persistOptions: OmitKeyof<PersistQueryClientOptions, 'queryClient'>;
  /** Optional callback executed after successful cache restoration */
  onSuccess?: () => Promise<unknown> | unknown;
  /** Optional callback executed after failed cache restoration */
  onError?: () => Promise<unknown> | unknown;
}

Usage Examples:

import React from 'react';
import { QueryClient } from '@tanstack/react-query';
import { PersistQueryClientProvider } from '@tanstack/react-query-persist-client';

const queryClient = new QueryClient();

// Basic usage
function App() {
  return (
    <PersistQueryClientProvider
      client={queryClient}
      persistOptions={{ persister: myPersister }}
    >
      <MyAppComponents />
    </PersistQueryClientProvider>
  );
}

// With success/error handling
function AppWithCallbacks() {
  const handleRestoreSuccess = () => {
    console.log('Query cache restored successfully');
    // Optional: trigger app-specific logic after restoration
  };

  const handleRestoreError = () => {
    console.error('Failed to restore query cache');
    // Optional: show user notification or fallback behavior
  };

  return (
    <PersistQueryClientProvider
      client={queryClient}
      persistOptions={{ 
        persister: myPersister,
        maxAge: 1000 * 60 * 60 * 24, // 24 hours
        buster: 'v1.0.0' // invalidate old caches
      }}
      onSuccess={handleRestoreSuccess}
      onError={handleRestoreError}
    >
      <MyAppComponents />
    </PersistQueryClientProvider>
  );
}

// With custom hydration options
function AppWithHydrationOptions() {
  return (
    <PersistQueryClientProvider
      client={queryClient}
      persistOptions={{ 
        persister: myPersister,
        hydrateOptions: {
          // Only restore queries, not mutations
          shouldDehydrateQuery: () => true,
          shouldDehydrateMutation: () => false,
        },
        dehydrateOptions: {
          // Custom dehydration settings for persistence
          shouldDehydrateQuery: (query) => query.state.status === 'success',
        }
      }}
    >
      <MyAppComponents />
    </PersistQueryClientProvider>
  );
}

Provider Behavior

The component follows this lifecycle:

  1. Mount: Sets isRestoring state to true
  2. Restoration: Calls persistQueryClientRestore with provided options
  3. Success/Error: Executes appropriate callback and sets isRestoring to false
  4. Subscription: After successful restoration, subscribes to cache changes for continuous persistence
  5. Unmount: Automatically unsubscribes from cache changes

IsRestoring Context

The provider uses IsRestoringProvider from @tanstack/react-query to communicate restoration state to child components.

import { useIsRestoring } from '@tanstack/react-query';

function MyComponent() {
  const isRestoring = useIsRestoring();
  
  if (isRestoring) {
    return <div>Loading cached data...</div>;
  }
  
  return <div>App content</div>;
}

Client Switching

The provider handles QueryClient changes correctly:

function AppWithClientSwitching() {
  const [client, setClient] = useState(() => new QueryClient());
  
  // When client changes, provider will:
  // 1. Unsubscribe from old client
  // 2. Restore cache in new client (if not already done)
  // 3. Subscribe to new client changes
  
  return (
    <PersistQueryClientProvider
      client={client}
      persistOptions={{ persister: myPersister }}
    >
      <button onClick={() => setClient(new QueryClient())}>
        Switch Client
      </button>
      <MyAppComponents />
    </PersistQueryClientProvider>
  );
}

Error Handling

When restoration fails:

  1. The persister's removeClient() method is called to clean up invalid data
  2. The onError callback is executed (if provided)
  3. A warning is logged in development mode
  4. The restoration process continues normally (queries will fetch fresh data)

StrictMode Compatibility

The component is designed to work correctly in React StrictMode without duplicate restoration attempts or subscriptions.

Install with Tessl CLI

npx tessl i tessl/npm-tanstack--react-query-persist-client

docs

core-persistence.md

experimental-features.md

index.md

persister-interface.md

react-provider.md

tile.json