Skip to content

Instantly share code, notes, and snippets.

@badsyntax
Last active September 9, 2023 08:20
Show Gist options
  • Save badsyntax/805364dbbf92372c3da183487c235f2e to your computer and use it in GitHub Desktop.
Save badsyntax/805364dbbf92372c3da183487c235f2e to your computer and use it in GitHub Desktop.
React Native, React Query Offline Persisted Queries & Mutations

These files demonstrates how to persist queries and mutations to offline state with the following behaviour:

  • Serve from query cache if offline
  • Persist mutations if offline, and resume mutations once online

It's important to set the online manager state before rendering the <QueryClientProvider />, for example:

<NetworkStateProvider>
  <QueryClientProvider>{children}</QueryClientProvider>
</NetworkStateProvider>
import type { QueryClient } from '@tanstack/react-query';
import { fetchSubmitForm, useSubmitForm } from './your/api';
import { DEFAULT_RETRIES } from './constants';
export function setMutationDefaults(queryClient: QueryClient) {
queryClient.setMutationDefaults([useSubmitForm.name], {
mutationFn: fetchSubmitForm,
retry: DEFAULT_RETRIES,
});
}
import { MutationCache, QueryCache, QueryClient } from '@tanstack/react-query';
import { setMutationDefaults } from './mutationDefaults';
export const queryClient = new QueryClient({
queryCache: new QueryCache(),
mutationCache: new MutationCache(),
defaultOptions: {
queries: {
refetchOnWindowFocus: false,
staleTime: 0, // always refresh if online
cacheTime: Infinity, // cache forever
},
mutations: {
cacheTime: Infinity, // cache forever
},
},
});
setMutationDefaults(queryClient);
import React, { type PropsWithChildren } from 'react';
import { PersistQueryClientProvider } from '@tanstack/react-query-persist-client';
import { onlineManager } from '@tanstack/react-query';
import { queryClient } from './queryClient';
import { storagePersister } from './storagePersister';
export function QueryClientProvider(props: PropsWithChildren) {
return (
<PersistQueryClientProvider
client={queryClient}
persistOptions={{ persister: storagePersister }}
onSuccess={async () => {
if (onlineManager.isOnline()) {
await queryClient.resumePausedMutations();
await queryClient.invalidateQueries();
}
}}
{...props}
/>
);
}
import { createSyncStoragePersister } from '@tanstack/query-sync-storage-persister';
import { MMKV } from 'react-native-mmkv';
const storage = new MMKV();
const clientStorage = {
setItem: (key: string, value: string) => {
storage.set(key, value);
},
getItem: (key: string) => {
const value = storage.getString(key);
return value === undefined ? null : value;
},
removeItem: (key: string) => {
storage.delete(key);
},
};
export const storagePersister = createSyncStoragePersister({
storage: clientStorage,
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment