Next.js Pages Router中useSearchParams为空且页面4次重渲染问题
解决Pages Router下查询参数同步到react-hook-form默认值的问题
问题核心原因
- API误用:
next/navigation的useSearchParams是App Router专属API,Pages Router环境下应使用next/router提供的useRouter钩子获取查询参数。 - 渲染时机不匹配:Suspense的异步渲染会触发组件多次更新,而react-hook-form的默认值若仅在初始化时设置,后续参数变化无法自动同步到表单。
具体解决方案
方案一:用Pages Router原生API同步表单值
- 导入Pages Router的
useRouter:
import { useRouter } from 'next/router';
- 结合路由参数初始化表单默认值,并监听路由变化同步更新:
import { useForm } from 'react-hook-form'; import { useRouter } from 'next/router'; import { useEffect } from 'react'; export default function TargetPage() { const router = useRouter(); const { register, setValue } = useForm({ defaultValues: { size: router.query.size || '' } }); // 监听路由query变化,实时同步到表单 useEffect(() => { if (router.query.size) { setValue('size', router.query.size); } }, [router.query.size, setValue]); return ( <input {...register('size')} /> ); }
方案二:服务端预取参数(适配SEO场景)
如果页面需要服务端渲染,可通过getServerSideProps提前获取查询参数,直接作为表单初始化值传入:
// 页面组件 export default function TargetPage({ initialSize }) { const { register } = useForm({ defaultValues: { size: initialSize || '' } }); return <input {...register('size')} />; } // 服务端获取查询参数 export async function getServerSideProps(context) { const { size } = context.query; return { props: { initialSize: size } }; }
额外优化建议
Pages Router对Suspense的支持有限,非必要场景下移除页面的Suspense包裹,可避免无意义的重复渲染。若必须保留Suspense,确保表单值的同步逻辑通过useEffect监听参数变化,保证每次参数更新都能同步到表单输入框。
内容的提问来源于stack exchange,提问作者Martial
相关产品推荐
相关产品推荐

