Skip to content

Next.js - 命令式路由

Next.js - 编程式导航 (命令式路由)

Section titled “Next.js - 编程式导航 (命令式路由)”

虽然 next/link 组件是处理页面间声明式导航(使用 <a> 标签)的标准方式,但 Next.js 也允许你通过编程方式进行导航,这通常被称为命令式路由。

当需要基于用户操作(如表单提交)、条件逻辑或异步操作完成后触发导航时,这种方式非常有用。

实现这一目标的主要方式是使用 useRouter hook。

  • 在 Pages Router 中,从 'next/router' 导入 useRouter。它提供了 router.push()、router.replace()、router.back() 等方法。

  • 在 App Router 中,从 'next/navigation' 导入 useRouter。它提供类似的方法(push、replace、back、forward、refresh)。注意,这个 hook 只能在 Client Components 中使用。

让我们修改一个示例页面(使用 Pages Router 环境)来演示使用 useRouter 进行编程式导航。

请看更新后的 pages/index.js:

import { useRouter } from 'next/router';
import Head from 'next/head';
function HomePage(props) {
// 获取路由对象
const router = useRouter();
const goToFirstPost = () => {
console.log('Navigating to /posts/first-post programmatically...');
router.push('/posts/first-post');
};
const goToPostById = (postId) => {
console.log(`Navigating to /posts/${postId}...`);
// 动态路由示例
router.push(`/posts/${postId}`);
// 或者使用对象语法以获取更多选项(例如,查询参数):
// router.push({
// pathname: '/posts/[id]',
// query: { id: postId, source: 'button_click' },
// });
};
return (
<>
<Head>
<title>Welcome to Next.js! (Imperative Routing)</title>
</Head>
<div>
<h1>Welcome to Next.js!</h1>
<p>Demonstrating Programmatic Navigation</p>
{/* 触发编程式导航的按钮 */}
<button onClick={goToFirstPost}>
Go to First Post (using router.push)
</button>
<br />
<br />
<button onClick={() => goToPostById('my-dynamic-post')}>
Go to Dynamic Post (ID: my-dynamic-post)
</button>
<br />
<br />
<div>
GitHub Stars (from props): {props.stars}
</div>
</div>
</>
);
}
// 示例数据获取(与路由本身无关)
export async function getServerSideProps(context) {
// 此函数在每个请求时运行
console.log('getServerSideProps executed for /');
// 示例:获取用户特定数据或实时信息
// 在这个简单的例子中,我们只获取当前时间
const res = await fetch('https://api.github.com/repos/vercel/next.js');
const json = await res.json();
return {
props: { stars: json.stargazers_count || 'N/A' },
};
}
export default HomePage;

在此示例中:

  • 我们从 'next/router' 导入了 useRouter。
  • 在组件内部,const router = useRouter() 获得了路由实例的访问权限。
  • 当点击第一个按钮时,goToFirstPost 函数调用 router.push('/posts/first-post')。
  • goToPostById 函数演示了如何使用模板字符串或对象语法,通过 router.push 导航到动态路由 (/posts/[id].js)。

启动服务器:

npm run dev
# 示例输出:
# ready - started server on 0.0.0.0:3000, url: http://localhost:3000
  1. 在浏览器中打开 http://localhost:3000。

  2. 点击 ‘Go to First Post (using router.push)’ 按钮。你应该会被导航到 /posts/first-post 页面,就像点击了一个 <Link> 组件一样。检查浏览器的开发者控制台查看日志消息。

  3. 导航回主页。

  4. 点击 ‘Go to Dynamic Post (ID: my-dynamic-post)’ 按钮。假设你已经在 pages/posts/[id].js 设置了一个页面,你应该会被导航到 /posts/my-dynamic-post。动态参数 my-dynamic-post 将在该页面组件中通过 router.query.id 获取。

router.push() 会将新的 URL 添加到浏览器的历史堆栈中,而 router.replace() 导航时不会添加新条目,而是替换当前历史记录中的 URL。