反应查询和查询无效问题

时间:2020-09-19 12:15:23

标签: reactjs react-query

我真的不知道如何清楚地询问,但是,我将首先粘贴我的代码并在下面询问。

function useToDos() {
  const queryCache = useQueryCache();
  const fetchTodos = useQuery(
    'fetchTodos',
    () => client.get(paths.todos).then(({ data }: any) => data),
    { enabled: false }
  );

  const createTodo = async ({ name ) =>
    await client.post(paths.todos, { name }).then(({ data }) => data);

  return {
    fetchTodos,
    createTodo: useMutation(createTodo, {
      onMutate: newItem => {
        queryCache.cancelQueries('fetchTodos');
        const previousTodos = queryCache.getQueryData('fetchTodos');
        queryCache.setQueryData('fetchTodos', old => [
          ...old,
          newItem,
        ]);
        return () => queryCache.setQueryData('fetchTodos', previousTodos);
      },
    }),
  };
}

如您所见,我正在尝试创建自己的自定义钩子来包装react-query功能。因此,我需要将fetchTodos查询设置为禁用,以便它不会立即运行。但是,这会中断所有后台数据的获取吗?

具体来说,当我运行createTodo并且触发onMutate方法时,我希望在后台更新fetchTodos查询,以便前端的待办事项列表为无需再次提出请求即可进行更新。但是似乎在最初将查询设置为禁用的情况下,后台更新不会生效。

由于我不认为将react-query钩子包装到自定义钩子库中是一个很好的主意,所以我可能会对此设置有更多疑问,但是现在,我将从这里开始。谢谢。 ?

2 个答案:

答案 0 :(得分:0)

如何将逻辑分为两个不同的钩子呢?而不是像useToDos这样的巨石?

这样,您就可以使用钩子进行提取:

const fetchData = _ => client.get(paths.todos).then(({ data }: any) => data)

export default function useFetchTodo(
  config = {
    refetchOnWindowFocus: false,
    enabled: false
  }
) {
  return useQuery('fetchData', fetchData, config)
}

在您的变异钩子中,您可以在createTodo之前手动重新获取

import useFetchTodo from './useFetchTodo'
//
const { refetch } = useFetchTodo()

// before createTodo
refetch()

答案 1 :(得分:0)

该突变不会自动触发重新引用。使用react-query实现此目的的方法是通过queryCache.invalidateQueries使突变后的缓存无效。从文档中:

invalidateQueries方法可用于根据查询的查询键或查询的任何其他功能上可访问的属性/状态来使高速缓存中的单个或多个查询无效和重新获取。默认情况下,所有匹配的查询都会立即标记为陈旧,活动的查询会在后台重新获取。

因此,您可以配置useMutation以在突变解决后使查询无效。示例:

function useToDos() {
  const queryCache = useQueryCache();
  const fetchTodos = useQuery(
    'fetchTodos',
    () => client.get(paths.todos).then(({ data }: any) => data),
    { enabled: false }
  );

  const createTodo = async ({ name ) =>
    await client.post(paths.todos, { name }).then(({ data }) => data);

  return {
    fetchTodos,
    createTodo: useMutation(createTodo, {
      onMutate: newItem => {
        queryCache.cancelQueries('fetchTodos');
        const previousTodos = queryCache.getQueryData('fetchTodos');
        queryCache.setQueryData('fetchTodos', old => [
          ...old,
          newItem,
        ]);
        return () => queryCache.setQueryData('fetchTodos', previousTodos);
      },

      onSettled: () => {
        cache.invalidateQueries('fetchTodos');
      }

    }),
  };
}