首页  >  问答  >  正文

在反应查询中突变后重新验证:分步指南

我在 next.js 应用程序上使用 react-query 实现了数据获取和更新的基本实现。 我的目标是在突变后更新数据。 目前,数据仅在选项卡刷新时更新。但如果没有用户交互,它就不会改变。

我发现选项卡刷新时发生数据更新是由于 refetchOnWindowFocus 默认行为。

但是服务器端更新数据后如何失效呢? 这是相关的代码片段。

注意:我正在使用 Hydration 来使用 react-query SSR 功能。文档

_app.jsx

const [queryClient] = React.useState(() => new QueryClient());

  return (
    <QueryClientProvider client={queryClient}>
      <Hydrate state={pageProps.dehydratedState}>
          <Component {...pageProps} />
      </Hydrate>
    </QueryClientProvider>

首页.jsx

const {data} = useQuery({
    queryKey: [queryKeys.key],
    queryFn: fetchData,
    staleTime: 1000 * 10, // this doesn't affect on anything
    //refetchInterval: 2000, this updates every 2 seconds
  });

  return (
    <div>
      <Article articles={data} />
    </div>
  );
   export const getServerSideProps = async () => {
  const queryClient = new QueryClient();
  await queryClient.prefetchQuery([queryKeys.key], fetchData);
  return { props: { dehydratedState: dehydrate(queryClient) } };
};

文章.jsx

const Article = ({articles}) => {
  const [title, setTitle] = useState("");
  const queryClient = new QueryClient();

  const { mutate } = useMutation({
    mutationFn: async (article) => {
      return await axios.post(url, article);
    },
    onSuccess: (data) => {
      console.log("data", data) // data is displayed, onSuccess is called
      queryClient.invalidateQueries({ queryKey: [queryKeys.key] });
    },
  });

  const changeTitleHandleClick = () => {
    mutate({
      id: new Date(),
      title: title
    });
    setTitle("");
  };
  ....

任何帮助将不胜感激

更新refetchInterval:2000每2秒更新一次,但这会每2秒触发一次网络请求,所以我不确定这是重新验证的最佳实践。

更新onSuccess方法内的控制台在突变时显示,这意味着逻辑有问题,因为即使密钥不同,这也应该有效:queryClient.invalidateQueries() 其中我没有指定任何键而是触发所有查询。 但即使这样也不会更新。为什么?

P粉752290033P粉752290033180 天前347

全部回复(2)我来回复

  • P粉677684876

    P粉6776848762024-03-26 11:50:35

    您实现突变的方式,它应该在成功突变后重新获取查询:

    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: [queryKeys.key] });
    },

    如果这不起作用,则说明您的突变不成功。检查onSuccess回​​调是否被调用。

    如果调用 onSuccess 回调,但未重新提取您的查询,则可能意味着 queryKey 不匹配。出于测试目的,请尝试将过滤器扩大到:

    queryClient.invalidateQueries()

    应该重新获取所有查询。如果有效,您就知道您的 queryKey 过滤器不匹配。

    仔细看看,你正在失效:

    queryKey: [queryKeys.key]

    但是在您的自定义挂钩中,您正在使用:

    queryKey: [queryKeys.articles]

    所以看起来它们确实不同,因此不匹配。另外,请务必使用 @tanstack/react-query-devtools 来更好地了解缓存中的查询和键。

    回复
    0
  • P粉231079976

    P粉2310799762024-03-26 11:47:03

    问题是在组件 Article.jsx 中,我在每个渲染中创建一个新的 QueryClient,因此它获得了一个新的缓存,因此没有更新。
    相反,我必须使用 useQueryClient 挂钩,它返回当前实例。
    const queryClient = useQueryClient();

    回复
    0
  • 取消回复