Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

react-query - getQueryData and setQueryData with pagination

I have some resource, let's call it todos.

I have list of it and user can delete on from list.

Before I implemented paginaiton that was looking like

const {data} = useQuery('todos', fetchTodos)

and in other place where I'm deleting it

  const [deleteTodo, deletingMutation] = useMutation(
    (id) => deleteTodo(id),
    {
      onSuccess: (data, deletedTodoId) => {
        const { todos } = queryCache.getQueryData<any>('todos');

        queryCache.setQueryData('todos', {
          todos: todos.filter(todo=>todo.id !== deletedTodoId),
        });
      },
    });

so in other place I'm just modyfing this data set called 'todos'

but After I implemented paginaiton things are more complicated because QueryKey isn't now just 'todos' but it's ['todos', page]

so when I'm deleting todo and calling in onSuccess this code queryCache.getQueryData<any>('todos');, it returns me undefined - because QueryKey contains additionally this page number.

How should I resolve it? Modyfing query data with paginated QueryKey.

like image 371
Kamil P Avatar asked Oct 30 '20 12:10

Kamil P


People also ask

How do you Refetch a react query?

Using auto refetching in React Query To use the auto refetch mode, you can pass an optional parameter to the React Query hook called refetchInterval . The value is in milliseconds. const { isLoading, data } = useQuery( 'vehicle', async () => { const { data } = await axios.

Is usePaginatedQuery deprecated?

In previous versions of React Query, pagination was achieved with usePaginatedQuery() , which has been deprecated at the time of writing.

What is stale time in React query?

StaleTime is the duration of the transition from fresh to stale state. If we are in the fresh state we will get the data from the cache only, but if we are in the stale state we may do a background fetch. CacheTime is the duration until inactive queries will be removed from the cache.


1 Answers

I think I'm too late for you but i had the same problem and want to share my solution (although it's a little bit hacky)

I wrote a function which returns all the related cache keys

const getRelatedCacheKeys = (queryClient, targetKey) => {
  return queryClient.getQueryCache().getAll()
    .map(query => query.queryKey)
    .filter(key => Array.isArray(key) ? key.includes(targetKey) : key === targetKey)
}

Then I call the setQueryData function for all related keys.

 onSuccess: data => {
   const keys = getRelatedCacheKeys(queryClient, 'key')
   keys.forEach(key => {
     queryClient.setQueryData(key, old => updateFn(old, data))
   })
 }

But the option to simply invalidate the cache seems tp be more practical

onSuccess: () => queryClient.invalidateQueries('key')

With this solution, all related keys also get invalidated

like image 124
David L. Avatar answered Sep 30 '22 19:09

David L.