Next.js项目中React Query获取的标签无法稳定渲染的问题求助
问题原因分析
- 冗余的状态复制:你用
useState手动复制react-query返回的data完全多余,且onSuccess回调里的data存在闭包问题,可能导致setTags无法正确更新状态。react-query本身已经内置了状态管理,直接使用返回的data即可。 - SSR下的查询触发逻辑:在Next.js SSR场景中,
react-query默认不会在服务端执行查询,客户端hydrate(水合)完成后,初始的查询状态是idle而非loading,导致你写的isLoading判断永远为false,加载提示自然不会显示。同时,react-query默认开启refetchOnWindowFocus,只有当页面重新聚焦时才会触发查询,这就是刷新后标签不显示、聚焦才出现的核心原因。 - 状态判断逻辑不准确:仅用
isLoading和isError无法覆盖react-query的所有状态(比如初始的idle状态),导致错误提示也无法触发。
修复方案
1. 简化组件代码,移除冗余状态
直接使用react-query返回的data和status字段来处理渲染逻辑:
const ArticlesPage = () => { const { status, data: tags = [], error } = useQuery('tags', getTags, { // 初始值设为空数组,避免组件接收undefined initialData: [], // 确保客户端水合完成后自动触发查询 refetchOnMount: true }) console.log('tags are:', tags) return ( <> {status === 'success' && <TagsComponent tags={tags} />} {status === 'loading' && <div> Loading tags...</div>} {status === 'error' && <div> Error fetching tags: {error.message}</div>} </> ) }
2. 确保_app.js中正确配置QueryClientProvider
这是react-query正常工作的基础,示例配置如下:
// pages/_app.js import { QueryClient, QueryClientProvider } from '@tanstack/react-query' const queryClient = new QueryClient({ defaultOptions: { queries: { refetchOnMount: true, refetchOnWindowFocus: true // 默认开启,保持即可 } } }) function MyApp({ Component, pageProps }) { return ( <QueryClientProvider client={queryClient}> <Component {...pageProps} /> </QueryClientProvider> ) } export default MyApp
3. 可选:SSR预取数据(优化体验)
如果希望刷新页面时直接显示标签,无需客户端二次请求,可以在页面的getServerSideProps中预取标签数据,作为initialData传给useQuery:
export async function getServerSideProps() { const initialTags = await getTags() return { props: { initialTags } } } const ArticlesPage = ({ initialTags }) => { const { status, data: tags, error } = useQuery('tags', getTags, { initialData: initialTags, // 已预取数据,无需自动重新获取 refetchOnMount: false }) // 渲染逻辑同前 }
内容的提问来源于stack exchange,提问作者blnks
相关产品推荐
相关产品推荐

