reactjs 如何使用react-query在变异后重新验证?

x3naxklr  于 2023-04-11  发布在  React
关注(0)|答案(2)|浏览(156)

我在next.jsapp上用react-query实现了一个数据获取和更新的基本实现,目标是在mutation后更新数据,目前数据只在tab刷新时更新,但没有用户交互的情况下,数据不会发生变化。
我发现标签刷新时的数据更新是因为refetchOnWindowFocus的默认行为。
但是如何在服务器端更新数据后失效。这里是相关的代码片段。

注意:我使用的是Hydration. Docs的react-query****SSR功能

_app.jsx

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

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

Home.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) } };
};

Article.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("");
  };
  ....

任何帮助将不胜感激

UPDATErefetchInterval: 2000每2秒更新一次,但这会每2秒触发一次网络请求,所以我不确定这是重新验证的最佳做法。
UPDATEonSuccess方法内部的控制台在mutation时显示,这意味着逻辑出了问题,因为即使键不同,这也应该起作用:queryClient.invalidateQueries(),我没有指定任何键,而是触发所有查询。但即使这样也不会更新。为什么?

f2uvfpb9

f2uvfpb91#

按照你实现变异的方式,它应该在成功变异后重新获取查询:

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

如果这不起作用,则可能是您的突变不成功。检查是否调用了onSuccess回调。
如果调用了onSuccess回调函数,但没有重新获取您的查询,这可能意味着queryKey不匹配。出于测试目的,请尝试将过滤器扩大到:

queryClient.invalidateQueries()

这应该会重新获取 * 所有 * 查询。如果这起作用,您就知道您的queryKey过滤器不匹配。
更仔细地看,你是无效的:

queryKey: [queryKeys.key]

但是在你的自定义钩子中,你使用的是:

queryKey: [queryKeys.articles]

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

watbbzwu

watbbzwu2#

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

相关问题