我在 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()
其中我没有指定任何键而是触发所有查询。
但即使这样也不会更新。为什么?
您实现突变的方式,它应该在成功突变后重新获取查询:
如果这不起作用,则说明您的突变不成功。检查
onSuccess
回调是否被调用。如果调用
onSuccess
回调,但未重新提取您的查询,则可能意味着queryKey
不匹配。出于测试目的,请尝试将过滤器扩大到:应该重新获取所有查询。如果有效,您就知道您的
queryKey
过滤器不匹配。仔细看看,你正在失效:
但是在您的自定义挂钩中,您正在使用:
所以看起来它们确实不同,因此不匹配。另外,请务必使用
@tanstack/react-query-devtools
来更好地了解缓存中的查询和键。问题是在组件
Article.jsx
中,我在每个渲染中创建一个新的 QueryClient,因此它获得了一个新的缓存,因此没有更新。相反,我必须使用
useQueryClient
挂钩,它返回当前实例。const queryClient = useQueryClient();