8

我有一些资源,我们称之为todos

我有它的列表,用户可以从列表中删除。

在我实施看起来像的 paginaiton 之前

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

在我删除它的其他地方

  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),
        });
      },
    });

所以在其他地方我只是修改这个数据集叫做'todos'

但是在我实现了 paginaiton 之后,事情变得更加复杂了,因为 QueryKey 现在不仅仅是'todos',而是['todos', page]

因此,当我删除待办事项并调用onSuccess此代码queryCache.getQueryData<any>('todos');时,它会返回我undefined- 因为 QueryKey 还包含此页码。

我应该如何解决?使用分页的 QueryKey 修改查询数据。

4

2 回答 2

3

我想我为时已晚,但我遇到了同样的问题并想分享我的解决方案(虽然它有点 hacky)

我写了一个返回所有相关缓存键的函数

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

然后我为所有相关键调用 setQueryData 函数。

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

但是简单地使缓存无效的选项似乎更实用

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

使用此解决方案,所有相关密钥也会失效

于 2021-01-07T16:15:04.293 回答
0

要直接回答您的问题,您可以提供更具体的密钥getQueryData

queryCache.getQueryData<any>(['todos', page]);

请注意,在分页中手动删除会产生移位问题:

const paginatedTodos = [ [1, 2], [3, 4], [5, 6] ];
deleteTodoId(3);
// you would get [ [1, 2], [4], [5, 6] ]
// instead of    [ [1, 2], [4, 5], [6] ]

您可以尝试修复页面中的“漏洞”,但为了避免任何不一致,最好简单地使所有todos查询无效以与服务器上的实际数据重新同步。

于 2020-11-19T11:21:02.823 回答