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)。
运行开发服务器
Section titled “运行开发服务器”启动服务器:
npm run dev
# 示例输出:# ready - started server on 0.0.0.0:3000, url: http://localhost:3000-
在浏览器中打开
http://localhost:3000。 -
点击 ‘Go to First Post (using router.push)’ 按钮。你应该会被导航到
/posts/first-post页面,就像点击了一个<Link>组件一样。检查浏览器的开发者控制台查看日志消息。 -
导航回主页。
-
点击 ‘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。