1

How can I configure React Query to retain data even when errors occur? This is my code but when there is error data would change to undefined

Additionally, it appears that the onError method is deprecated in the latest version of React-Query Is there an alternative solution to prevent the existing data from becoming undefined in case of an error?

import { useState } from 'react';
import { useQuery } from '@tanstack/react-query';
import { getDashboard } from '../dashboard/query';

function Dashboard() {
  const [todayDate, setTodayDate] = useState('');

  const { data, isError, isSuccess, isFetching, error } = useQuery(
     ['dashboard', { date: todayDate }],
     getDashboard,
   {
    keepPreviousData: true, // Keep previous data while fetching new data
    retry: false,
   }
  onError(error) {
    if (error) {
      queryClient.setQueryData(['dashboard', getDashboard], query.data);
    }
  }
 );

 return (
   <div>
     { isError && error ? <div>error.message < /div> : null}
     <div> { data!.data.name } </div>
   </div>
  );
}
Ahmed Sbai
  • 10,695
  • 9
  • 19
  • 38
Dvlpr
  • 1,439
  • 1
  • 11
  • 21

2 Answers2

2

The onError callback, example from docs:

 useQuery({
    queryKey: ['todos'],
    queryFn: fetchTodos,
    // ⚠️ looks good, but is maybe _not_ what you want
    onError: (error) =>
      toast.error(`Something went wrong: ${error.message}`),
  })

If data is still undefined there, then you can try this workaround:

const [myData, setMyData] = useState()
// ...
useEffect(() => {
 if (data && !Object.is(JSON.stringify(data), JSON.stringify(myData))) {
  setMyData(data)
} 
},[data])

This way each time data changes, if it is defined, and different from the stored value, you store it in myData state.

Now even if data becomes undefined when you need it, you can still use myData instead.


You should be able to use myData from inside the onError callback, but if it is not the case, you can still do this:

useEffect(() => {
 if (error) {
  // execute your logic, you can use `myData` state
} 
},[error])

Again, each time error changes and if it is defined, you do what you have to.

Ahmed Sbai
  • 10,695
  • 9
  • 19
  • 38
2

when there is error data would change to undefined

This is not true. When a query is refetched that previously had data, getting an error will not remove the error. However, what you are seeing is a totally different situation:

You've set keepPreviousData to true, so react query will give you back data from the previous query key while fetching data for the first time for the current query key. If that fetch fails, you will get undefined because there is no data in the cache for this specific query key.

keepPreviousData is a mechanism to avoid hard loading states. The data you see from the previous query will only be shown until the first fetch for the current query has completed - either successfully or with an error.

If you expect the data from the previous query to be shown even if there is an error for the current query, then sorry, this is not how it works and not possible.

TkDodo
  • 20,449
  • 3
  • 50
  • 65