#题引:我认为跟着官方文档学习不会走歪路
在介绍路由导航之前先了解下客户端组件和服务端组件
服务端组件(Server Components)
(1) 渲染方式:
- 在服务器上渲染,生成 HTML 后发送到客户端。
- 适合用于静态内容或不需要频繁更新的内容。
(2)数据获取:
- 可以直接在组件中使用服务器端的数据获取方法
- 支持直接读取数据库或调用 API,避免了客户端的数据请求。
(3)生命周期:
- 生命周期与服务器相关,不会在客户端重新渲染。
- 不支持使用客户端特有的生命周期方法(如 useEffect)。
(4)性能:
- 由于在服务器上渲染,初始加载时可以更快地展示内容。
- 减少了客户端的 JavaScript 负担,提升了性能。
(5)使用场景:
- 适合用于展示静态内容、SEO 优化、数据密集型的页面。
客户端组件(Client Components)
(1)渲染方式:
- 在客户端渲染,通常是通过 JavaScript 动态生成内容。
- 可以根据用户交互或状态变化进行更新。
(2)数据获取:
- 需要在组件内部使用客户端数据获取方法,如 fetch 或其他 API 调用。
- 数据请求通常在组件的生命周期内进行,依赖于用户交互。
(3)生命周期:
- 支持 React 的所有生命周期方法,包括 useEffect 和 useState。
- 可以响应用户的操作和状态变化。
(4)性能:
- 初次加载时可能较慢,因为需要下载 JavaScript 并在客户端渲染。
- 对于动态内容和交互性较强的页面,客户端组件更为合适。
(5)使用场景:
- 适合用于需要频繁更新的内容、用户交互复杂的部分(如表单、动态列表)。
Next.js 中有四种在路由之间进行导航的方式
- 使用
<Link>
组件 - 使用 useRouter hook (客户端组件)
- 使用 redirect 函数 (服务器组件)
- 使用原生 History API
Link 组件 (官方推荐)
<Link>
是一个内置组件,它扩展了 HTML 的 a标签,提供 预获取
和客户端路由导航功能。这是 Next.js 中进行路由导航的主要推荐方式。
import Link from 'next/link'export default function Page() {return <Link href="/dashboard">仪表盘</Link>
}
预获取
:一种在用户访问路由之前在后台预加载该路由的方式。
对于link组件,当路由在用户视口中可见时,会自动预获取。预获取会在页面首次加载时或通过滚动进入视图时发生。Next.js 会自动预获取链接指向的页面。当用户将鼠标悬停在链接上时,Next.js 会在后台请求该页面的资源。
useRouter() hook
useRouter hook 允许你在客户端组件中以编程方式更改路由
'use client'import { useRouter } from 'next/navigation'export default function Page() {const router = useRouter()return (<button type="button" onClick={() => router.push('/dashboard')}>仪表盘</button>)
}
redirect 函数
对于服务器组件,请使用 redirect 函数。
import { redirect } from 'next/navigation'async function fetchTeam(id: string) {const res = await fetch('https://...')if (!res.ok) return undefinedreturn res.json()
}export default async function Profile({ params }: { params: { id: string } }) {const team = await fetchTeam(params.id)if (!team) {redirect('/login')}// ...
}
使用原生 History API
Next.js 允许你使用原生的 window.history.pushState 和 window.history.replaceState 方法来更新浏览器的历史记录堆栈,而无需重新加载页面。
pushState 和 replaceState 调用会集成到 Next.js 路由器中,允许你与 usePathname 和 useSearchParams 同步。
总结
App Router 采用混合方式进行路由和导航。在服务器端,你的应用程序代码会按路由段自动进行代码分割成更小的包,供浏览器下载和执行。而在客户端,Next.js 会预获取和缓存路由段。这意味着,当用户导航到新路由时,浏览器不会重新加载页面,只有变化的路由段会重新渲染——这改善了导航体验和性能。