在 Next.js 中,Router
和 useRouter
都是用于路由管理的核心 API,但它们的适用场景和使用方式有重要区别:
1. Router
(Next.js 的路由对象)
特点:
- 低级别路由对象:直接从
next/router
导入的原始路由类 - 需要手动订阅更新:不会自动触发组件重渲染
- 适用于非组件环境:如 utility 文件、API 路由等
典型用法:
import { Router } from "next/router";
// 编程式导航(在非组件环境中)
Router.push("/dashboard");
// 监听路由事件
Router.events.on("routeChangeStart", (url) => {
console.log("路由开始变化:", url);
});
常用方法/事件:
Router.push()
编程式导航Router.replace()
替换当前路由(不保留历史记录)Router.events.on()
监听路由事件
2. useRouter
(React Hook)
特点:
- 组件级 Hook:只能在 React 组件或自定义 Hook 中使用
- 自动订阅更新:路由变化时会触发组件重渲染
- 访问当前路由状态:可直接获取 query、pathname 等实时信息
典型用法:
import { useRouter } from "next/router";
function Component() {
const router = useRouter();
// 获取当前路由信息
console.log(router.pathname); // 当前路径
console.log(router.query); // 查询参数
// 编程式导航
const handleClick = () => {
router.push("/profile?id=123");
};
return <button onClick={handleClick}>跳转</button>;
}
常用属性/方法:
router.query
获取动态路由参数和查询字符串router.pathname
当前路由路径(不包含查询参数)router.push()
组件内的编程式导航router.asPath
包含查询参数的实际 URL
何时选择?
-
用
useRouter
如果:- 在 React 组件中需要响应式路由数据
- 需要访问当前路由参数(如动态路由
[id].js
) - 要实现基于路由的 UI 逻辑(如高亮导航菜单)
-
用
Router
如果:- 在非组件文件中操作导航(如
utils/auth.js
) - 需要全局监听路由事件(如页面加载进度条)
- 在
_app.js
中设置全局路由处理器
- 在非组件文件中操作导航(如
组合使用示例
// utils/navigation.js
import { Router } from "next/router";
export const logout = () => {
Router.push("/login"); // 在工具文件中使用
};
// components/Profile.js
import { useRouter } from "next/router";
export default function Profile() {
const router = useRouter();
// 响应式获取URL参数
const { userId } = router.query;
return <div>User ID: {userId}</div>;
}
注意事项
useRouter
必须在组件顶层调用(遵守 Hook 规则)Router.events
的监听器需要手动移除(防止内存泄漏)useEffect(() => { const handler = (url) => console.log(url); Router.events.on("routeChangeStart", handler); return () => Router.events.off("routeChangeStart", handler); }, []);
- 在 Next.js 13+ 的 App Router 中,推荐使用新的
usePathname
和useSearchParams
替代部分功能