为何使用useRouter时出现“NextRouter was not mounted”错误?
问题:Next.js浅路由使用时出现NextRouter未挂载错误
我尝试用Next.js的浅路由功能,通过URL查询参数(如page?type=digital)渲染对应组件,写了下面的客户端组件代码:
'use client'; import { useEffect } from 'react'; import { useRouter } from 'next/router'; function Page() { const router = useRouter(); useEffect(() => { // You might not need to navigate on mount if the URL is expected to be set correctly before loading the page. // If you do need to set an initial `type`, consider doing so conditionally or in response to a user action. }, []); // Optionally, listen for changes in the `type` query parameter useEffect(() => { if (router.query.type) { // Handle changes, e.g., fetch data or update state based on the new `type` // This is more relevant if there are additional side effects or data fetching based on the query parameter. } }, [router.query.type]); function renderForm() { const { type } = router.query; switch (type) { case 'digital': return <div>Digital Form</div>; case 'physical': return <div>Physical Form</div>; default: return null; } } return <div>{renderForm()}</div>; } export default Page;
但执行const router = useRouter();时出现错误:
Error: NextRouter was not mounted. https://nextjs.org/docs/messages/next-router-not-mounted
请问该问题的原因是什么?
原因分析
这个错误的核心是路由API版本不匹配:
- 你当前使用的是Next.js 13+的App Router模式,但代码里导入的
useRouter来自next/router——这个API属于旧的Pages Router,在App Router环境中无法正常挂载,因此抛出该错误。 - 在App Router的客户端组件中,需要使用
next/navigation包提供的路由工具:用useSearchParams获取查询参数,用同包导出的useRouter处理路由跳转(包括浅路由)。
修正方案示例
改用App Router的正确API后,代码可以调整为:
'use client'; import { useEffect } from 'react'; import { useSearchParams, useRouter } from 'next/navigation'; function Page() { const searchParams = useSearchParams(); const router = useRouter(); // 监听查询参数变化 useEffect(() => { const type = searchParams.get('type'); if (type) { // 这里可以添加查询参数变化后的逻辑,比如数据请求、状态更新 } }, [searchParams]); // 根据type渲染对应组件 function renderForm() { const type = searchParams.get('type'); switch (type) { case 'digital': return <div>Digital Form</div>; case 'physical': return <div>Physical Form</div>; default: return null; } } // 浅路由跳转示例 const switchType = (newType) => { router.push(`/page?type=${newType}`, { shallow: true }); }; return ( <div> {renderForm()} <button onClick={() => switchType('digital')}>切换到Digital表单</button> <button onClick={() => switchType('physical')}>切换到Physical表单</button> </div> ); } export default Page;
内容的提问来源于stack exchange,提问作者wyc
相关产品推荐
相关产品推荐

