Next.js中如何仅在URL参数加载后向服务器发送请求?
问题解决方案
一、解决请求携带undefined文章ID的问题
核心原因是Next.js的router.query.id在页面初始渲染阶段可能尚未完成解析(比如客户端路由跳转时,路由参数需要短暂时间加载),导致react-query直接用undefined发起请求。可以通过以下两种方案处理:
1. 用react-query的enabled选项控制请求时机
在useQuery中配置enabled,仅当id存在时才触发请求:
import { useQuery } from '@tanstack/react-query'; import { useRouter } from 'next/router'; export default function PostPage() { const router = useRouter(); const { id } = router.query; const { data: post } = useQuery({ queryKey: ['post', id], queryFn: () => fetch(`/api/posts/${id}`).then(res => res.json()), enabled: !!id, // 仅id存在时发起请求 }); if (!id) return <div>加载中...</div>; return <div>{post?.title}</div>; }
2. 监听id变化手动触发请求
如果需要更精细的控制,可结合useEffect监听id的变化,手动触发react-query请求:
import { useQuery, useQueryClient } from '@tanstack/react-query'; import { useRouter } from 'next/router'; import { useEffect } from 'react'; export default function PostPage() { const router = useRouter(); const { id } = router.query; const queryClient = useQueryClient(); const { data: post } = useQuery({ queryKey: ['post', id], queryFn: () => fetch(`/api/posts/${id}`).then(res => res.json()), enabled: false, // 禁用自动触发 }); useEffect(() => { if (id) { queryClient.fetchQuery({ queryKey: ['post', id], queryFn: () => fetch(`/api/posts/${id}`).then(res => res.json()) }); } }, [id, queryClient]); if (!id) return <div>加载中...</div>; return <div>{post?.title}</div>; }
二、关于页面进入时发送两次请求的问题
你看到的两次请求是React 18 Strict Mode在开发环境下的特性:它会刻意重复执行组件渲染、副作用(包括react-query的请求),目的是提前检测潜在bug(比如未清理的副作用、非幂等操作)。
- 生产环境下不会出现该情况,Strict Mode仅在开发环境生效,不会浪费生产资源。
- 若要在开发环境关闭该特性,可修改
next.config.js,将reactStrictMode设为false:
/** @type {import('next').NextConfig} */ const nextConfig = { reactStrictMode: false, // 其他配置项... }; module.exports = nextConfig;
但不建议这么做,Strict Mode能帮你提前发现隐藏问题,避免上线后出现bug。
内容的提问来源于stack exchange,提问作者Julio Raposo
相关产品推荐
相关产品推荐

