NextJS+React-query同页面重复点击Link后查询丢失问题求助
问题分析与解决方案
问题原因
当你在/client页面点击侧边栏的同路由<Link>时,Next.js的<Link>组件会触发页面组件的卸载再重新挂载(即使URL无变化)。这会导致Client组件被卸载,React Query中关联的['clients']查询实例因失去活跃订阅者,被默认垃圾回收机制清理,因此在devtools中消失。
另外你的useSearchClient设置了enabled: false,查询完全依赖refetch触发,组件卸载后没有订阅者维持缓存,进一步加速了查询的清理。
解决方案
方案1:阻止同路由Link的跳转行为
修改侧边栏的Link组件,判断当前路径是否与目标路径一致,一致则阻止默认跳转,避免组件重新挂载:
import Link from 'next/link' import { useRouter } from 'next/router' // 侧边栏组件内部 const router = useRouter() const handleClientLinkClick = (e: React.MouseEvent) => { if (router.pathname === '/client') { e.preventDefault() // 可选:若需手动刷新数据,可通过Context/状态传递refetch方法并调用 } } <Link href="/client" onClick={handleClientLinkClick}>client</Link>
方案2:调整React Query缓存策略
给useSearchClient配置更长的cacheTime,让查询在组件卸载后仍保留在缓存中,同时建议将filters加入queryKey,保证不同参数的查询缓存独立:
export const useSearchClient: UseSearchClient = (filters) => { return useQuery({ queryKey: ['clients', filters], // 加入filters确保缓存区分不同筛选条件 queryFn: queryFn(filters), enabled: false, cacheTime: 5 * 60 * 1000, // 设置5分钟缓存时长,可按需调整 }) }
方案3:将查询逻辑提升到全局层级
把useSearchClient的查询逻辑移到_app.tsx这类全局组件中,即使Client组件卸载,查询仍有活跃订阅者,不会被清理:
// _app.tsx function MyApp({ Component, pageProps }) { const filters = {} // 按实际场景获取筛选条件 const { data: clientsData } = useSearchClient(filters) // 通过props或Context将数据传递给Client组件 return <Component {...pageProps} clientsData={clientsData} /> }
最优建议
优先选择方案1,它从根源上避免了不必要的组件卸载,既解决查询消失问题,也提升了页面性能。同时务必将filters加入queryKey,避免不同筛选条件的查询缓存互相覆盖。
内容的提问来源于stack exchange,提问作者Haki
相关产品推荐
相关产品推荐

