如何在Next.js布局组件中保持React Query数据同步更新?
问题:Next.js + React Query 4 全局认证状态联动失效
我在Next.js应用中使用@tanstack/react-query@4进行状态管理与数据获取,通过自定义useUser()钩子管理认证状态,该钩子在全局布局的导航栏和两个相同的用户信息页面中均有使用。首次打开应用时,页面与导航栏的数据共享正常,查询键["user"]的观察者计数为2;但切换页面并重新获取该键数据时,导航栏的该键观察者似乎被解绑,数据不再更新,观察者计数变为1,求保持数据联动的解决方案。
解决方案
统一
useUser()钩子的查询配置
确保所有调用useUser()的地方使用完全一致的查询键["user"],并在钩子内部统一设置查询缓存参数,避免不同组件单独配置导致缓存隔离。示例代码:function useUser() { return useQuery({ queryKey: ["user"], queryFn: fetchCurrentUser, staleTime: 5 * 60 * 1000, // 设置缓存新鲜时间,避免频繁重新请求 cacheTime: 10 * 60 * 1000, // 延长缓存保留时间,防止导航栏观察者卸载后缓存被回收 }); }保证导航栏组件持久挂载
将导航栏放在Next.js的根布局组件中(如layout.tsx),而非页面组件内部。这样页面切换时导航栏不会被卸载,useUser()的观察者会持续存在,维持查询键的观察者计数。主动触发缓存同步更新
如果需要在页面切换时更新用户数据,可在页面组件中调用queryClient.invalidateQueries(["user"])触发全局缓存重新获取,确保导航栏和页面的数据同步:"use client"; import { useQueryClient } from "@tanstack/react-query"; function UserPage() { const queryClient = useQueryClient(); useEffect(() => { // 页面加载时触发用户数据更新 queryClient.invalidateQueries(["user"]); }, []); // ...页面逻辑 }确认QueryClientProvider的全局范围
确保QueryClientProvider包裹整个应用(包括根布局和所有页面),全局共享同一个QueryClient实例。示例配置:// app/providers.tsx "use client"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; const queryClient = new QueryClient({ defaultOptions: { queries: { refetchOnWindowFocus: false, // 根据业务需求调整 }, }, }); export function ReactQueryProvider({ children }: { children: React.ReactNode }) { return ( <QueryClientProvider client={queryClient}> {children} </QueryClientProvider> ); }随后在根
layout.tsx中引入该Provider,包裹所有子内容。
内容的提问来源于stack exchange,提问作者Iftach
相关产品推荐
相关产品推荐

