Home > OS >  How to make React-Query return cached/previous data if network is not connected/available?
How to make React-Query return cached/previous data if network is not connected/available?

Time:10-06

I've modifying some existing React Native code where I've to check if network connection is available or not. If it is available, I've to fetch new data from API, otherwise I've to use cached data. This is what I've achieved so far:

export const useStudentData = (
  studentId: Student['id']
): UseQueryResult<Student, Error> => {
  
    const queryKey = studentDataKeys.list({ studentIdEq: studentData?.id });
    const queryClient = useQueryClient();
    const {isConnected} = useNetInfo();
  
    if(!isConnected){
      // return previously cached data here
    }
  
    const data = useQuery<Student, Error>(
        studentDataKeys.detail(studentId),
      async () => {
        const { data: student } = await StudentDataAPI.fetchDataById(studentId);
  
        return StudentData.deserialize({
          ...studentData,
          assignments: studentData.assignments?.filter((assignment) => assignment.submitted)
        });
      },
      {
        staleTime: 1000 * 60 * 60 * 10,
        retry: 0,
        initialData: () => {
          const previousStudentData = queryClient.getQueryData<Student[]>(queryKey);
  
          return previousStudentData?.find((studentData) => studentData.id === studentId);
        },
        initialDataUpdatedAt: queryClient.getQueryState(queryKey)?.dataUpdatedAt,
        one rror() {
          console.log("Error with API fetching");
        }
      }
    );
  
    return data;
  };

How can I modify it so that if network connection is present, it should download new data otherwise return previous/old data that was cached in previous successful call?

CodePudding user response:

You can rely on the queryKey for that. In detail, react-query caches the result based on the key. Your current key is studentDataKeys.detail(studentId), what about replacing it with [studentDataKeys.detail(studentId), isConnected]?

CodePudding user response:

Instead of reinventing the wheel, you can use the existing solution. That is:

import NetInfo from '@react-native-community/netinfo'
import { onlineManager } from '@tanstack/react-query'

onlineManager.setEventListener(setOnline => {
  return NetInfo.addEventListener(state => {
    setOnline(!!state.isConnected)
  })
})

After implementing this, react-query will automatically refetch your data when the device is back online.

  • Related