我在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("");
};
....
任何帮助将不胜感激
UPDATE:refetchInterval: 2000
每2秒更新一次,但这会每2秒触发一次网络请求,所以我不确定这是重新验证的最佳做法。
UPDATE:onSuccess
方法内部的控制台在mutation时显示,这意味着逻辑出了问题,因为即使键不同,这也应该起作用:queryClient.invalidateQueries()
,我没有指定任何键,而是触发所有查询。但即使这样也不会更新。为什么?
2条答案
按热度按时间f2uvfpb91#
按照你实现变异的方式,它应该在成功变异后重新获取查询:
如果这不起作用,则可能是您的突变不成功。检查是否调用了
onSuccess
回调。如果调用了
onSuccess
回调函数,但没有重新获取您的查询,这可能意味着queryKey
不匹配。出于测试目的,请尝试将过滤器扩大到:这应该会重新获取 * 所有 * 查询。如果这起作用,您就知道您的
queryKey
过滤器不匹配。更仔细地看,你是无效的:
但是在你的自定义钩子中,你使用的是:
所以看起来它们确实是不同的,因此不匹配。另外,一定要使用
@tanstack/react-query-devtools
来更好地了解缓存中的查询和键。watbbzwu2#
问题是,在组件
Article.jsx
中,我在每个渲染器中创建了一个新的QueryClient,因此它得到了一个新的缓存,因此没有更新。相反,我不得不使用
useQueryClient
钩子,它返回当前示例。const queryClient = useQueryClient();