I couldn’t find much information on tanstack's GitHub issues, blog posts, or YouTube videos
I’ve tried logging the results from async-storage using the default key of the react query cache as a troubleshooting step, but nothing ever comes back, always undefined
Ive configured an async storage persister as per the documentations, but nothing seems to be persisted across cold-starts. In the case of the client-only-cache example below, at the point its created, it exsits, but if the hard is quit from multitasking, and re-opened, the cache data is undefined
Here’s my query client config: https://pastebin.com/wMdcHxsz
import { createAsyncStoragePersister } from '@tanstack/query-async-storage-persister'
import AsyncStorage from '@react-native-async-storage/async-storage';
import { MutationCache, QueryClient } from '@tanstack/react-query'
import { CrashReporting } from 'instabug-reactnative';
export const persister = createAsyncStoragePersister({
storage: AsyncStorage,
throttleTime: 500,
key: "REACT_QUERY_OFFLINE_CACHE",
});
export const queryClient = new QueryClient({
defaultOptions: {
queries: {
networkMode: 'online',
staleTime: Infinity,
cacheTime: Infinity, // 24 hours
// staleTime: Infinity, // longer staleTimes result in queries not being re-fetched as often
refetchOnReconnect: 'always',
retry: 3,
retryDelay: 3000,
refetchOnWindowFocus: true,
refetchOnMount: true
},
mutations: {
cacheTime: Infinity,
}
},
mutationCache: new MutationCache({
onSuccess: (data) => {
console.log('[ Mutation Cache Processed ]:', data)
},
onError: (error) => {
console.log('[ Mutation Cache Error ]:', error)
CrashReporting.reportError(error);
throw error
}
})
});
Here’s my App.tsx (sans imports): https://pastebin.com/WPkgWLMJ
function App(): JSX.Element {
useEffect(() => {
SplashScreen.hide();
onlineManager.setEventListener((setOnline) => {
return NetInfo.addEventListener((state) => {
setOnline(!!state.isConnected);
});
});
}, []);
return (
<ThemeProvider theme={theme}>
<DevToolProvider>
<QueryErrorResetBoundary>
{({ reset }) => (
<ErrorBoundary onReset={reset}>
<PersistQueryClientProvider
client={queryClient}
persistOptions={{
persister,
maxAge: Infinity
}}
onSuccess={() => {
// resume mutations after initial restore from localStorage was successful
queryClient.resumePausedMutations().then(() => {
queryClient.invalidateQueries();
});
}}>
<NavigationContainer
ref={navigationRef}
fallback={
<View
style={{
justifyContent: 'center',
alignItems: 'center'
}}>
<ActivityIndicator animating={true} />
</View>
}>
<RootNavigator />
</NavigationContainer>
<ConnectionLostAlert />
<EnvFlag />
</PersistQueryClientProvider>
</ErrorBoundary>
)}
</QueryErrorResetBoundary>
</DevToolProvider>
</ThemeProvider>
);
}
export default CodePush(codepushConfig)(App);
Heres an example of setting a client-only query cache (no api calls reset this cache):
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { QueryKeys } from '../queries/queryKeys';
import { ProjectJob } from '../ProjectJobsService/types';
export default function useCreateMissingPhotos() {
const queryClient = useQueryClient();
queryClient.setMutationDefaults([QueryKeys.MissingPhotos], {
mutationFn: async () => {} // This is a client-only cache, we don't want to do anything when network is restored
});
return useMutation({
mutationKey: [QueryKeys.MissingPhotos],
onMutate: async (data: ProjectJob) => {
await queryClient.cancelQueries([QueryKeys.MissingPhotos]);
const previousState = queryClient.getQueryData([QueryKeys.MissingPhotos]);
queryClient.setQueryData(
[QueryKeys.MissingPhotos],
(old: ProjectJob[] | undefined) => (old ? [...old, data] : [data])
);
return { previousState };
},
onError: (err, newState, context) => {
queryClient.setQueryData(
[QueryKeys.MissingPhotos],
context?.previousState
);
},
onSettled: (data, error, newState) => {
queryClient.invalidateQueries({
queryKey: [QueryKeys.MissingPhotos]
});
}
});
}
Not sure what’s wrong here, any advice would be appreciated
Persisting React Query's cache across app launches in a React Native environment requires a correct setup of asynchronous storage along with React Query. From your configuration, you have attempted to set up
@tanstack/query-async-storage-persister
for this purpose, which is a good step.However, if the cache is not being persisted across launches, check first that Async Storage is correctly installed and configured in your React Native project. It might be helpful to test Async Storage independently of React Query to confirm that it is working as expected. Check that
@react-native-async-storage/async-storage
is installed in your project (npm list @react-native-async-storage/async-storage
oryarn list --pattern @react-native-async-storage/async-storage
in your project directory).And create a simple function to set, get, and remove a value in Async Storage.
For instance:
After that:
createAsyncStoragePersister
method, you have specified akey
of"REACT_QUERY_OFFLINE_CACHE"
. Ensure that this key does not collide with any other keys used in Async Storage in your application.queryClient
configuration, you have setcacheTime
toInfinity
. While this should keep the data in cache, it might be worth experimenting with finite values to observe any different behavior.PersistQueryClientProvider
, you have setmaxAge
toInfinity
inpersistOptions
. Similar to thecacheTime
setting, you might want to experiment with finite values.QueryClient
andPersistQueryClientProvider
context to ensure it is functioning as expected. You might want to manually interact with thepersister
to save and retrieve a test object to/from Async Storage.mutationCache
anduseMutation
hook for any issues.Given that Async Storage is functioning correctly in other areas of the application, and various configurations for
maxAge
andcacheTime
have been tested, as well as manual calls topersistQueryClient
on app mount have been attempted without success, that should mean there might be an issue specifically related to the interaction between React Query and Async Storage.Review first the configuration of
PersistQueryClientProvider
andQueryClient
to make sure they align with the documentation and examples provided by React Query and@tanstack/query-async-storage-persister
.I would assume you have the latest stable versions, particularly for
@tanstack/react-query
,@tanstack/query-async-storage-persister
, and@react-native-async-storage/async-storage
.Check if the data being stored and retrieved from the cache is being serialized and deserialized correctly. The data stored in Async Storage needs to be stringified and parsed correctly when retrieved.
I would also log the data being saved to and retrieved from Async Storage to see if it is being stored and retrieved as expected. That includes checking the data just before it is persisted, and immediately after it is retrieved.
If the issue persists, try and create a simplified scenario with minimal configuration to test the persistence of React Query cache across app launches: that should help in isolating the issue.