ZQ
About 3570 wordsAbout 12 min
reactNextJs
2024-7-8
This note records things about Route Basicr.
Next.js使用基于文件系统的路由器,其中文件夹用于定义路由。 每个文件夹表示映射到 URL 段的路由段。若要创建嵌套路由,可以将文件夹嵌套在彼此内部。
page.js
文件用于使路由段可公开访问。
在此示例中, /dashboard/analytics
URL 路径不可公开访问,因为它没有相应的 page.js
文件。此文件夹可用于存储组件、样式表、图像或其他共置文件。
在dashboard
的page.js
中添加内容,便能在对应的路由中查看渲染后的内容。
// `app/dashboard/page.tsx` is the UI for the `/dashboard` URL
export default function Page() {
return <h1>Hello, Dashboard Page!</h1>
}
Tips:
.js
, .jsx
, or .tsx
file extensions can be used for Pages.page.js
file is required to make a route segment publicly accessible.布局是在多个路由之间共享的 UI。在导航时,布局会保留状态,保持交互式,并且不会重新渲染。布局也可以嵌套。
默认情况下,文件夹层次结构中的布局是嵌套的,这意味着它们通过其 children
prop 包装子布局。您可以通过在特定路段(文件夹)内添加 layout.js
来嵌套布局。
例如,若要为 /dashboard
路由创建布局,请在 dashboard
文件夹中添加一个新 layout.js
文件:
如图所示,在使用布局时,根布局将包裹仪表盘布局。
Tips:
.js
, .jsx
, or .tsx
file extensions can be used for Layouts.<html>
and <body>
tags.layout.js
and page.js
file are defined in the same folder, the layout will wrap the page.useSelectedLayoutSegment
or useSelectedLayoutSegments
in a Client Component.依赖于 useEffect
(例如记录页面浏览量)和 useState
(例如每页反馈表)的功能。
更改默认框架行为。例如,布局中的“悬念边界”仅在首次加载布局时显示回退,而在切换页面时不显示回退。对于模板,回退将显示在每个导航上。
可以通过从 template.js
文件中导出默认的 React 组件来定义模板。组件应接受 children
prop。布局时显示回退,而在切换页面时不显示回退。对于模板,回退将显示在每个导航上。
page.js
会被包裹在同级的template
中,再包裹在layout
中。
在主页中插入link
import Link from 'next/link'
export default function Page() {
return
<div>
## 链接到其他路由
<Link href="/dashboard" className="outlined text-orange-400">Dashboard</Link>
<strong className="text-violet-500"> This is homepage.</strong>
</div>
}
添加一些条件来判断跳转状态,如果当前不在dashboard
则跳转。
"use client";
import Link from "next/link";
import { postcss } from "tailwindcss";
import { usePathname } from "next/navigation";
export default function Page() {
const pathname = usePathname();
return (
<div>
<Link
href="/dashboard"
className={`link ${
pathname === "/dashboard" ? "text-green-400" : "text-gray-300"
}`}
>
Dashboard
</Link>
<strong className="text-violet-500">This is homepage.</strong>
</div>
);
}
滚动到当期页面的某个部分。
useRouter()
钩子useRouter
允许您以编程方式从客户端组件更改路由。'use client'
import { useRouter } from 'next/navigation'
export default function Page() {
const router = useRouter()
return (
<button type="button" onClick={() => router.push('/dashboard')}>
Dashboard
</button>
)
}
Recommendation: Use the
<Link>
component to navigate between routes unless you have a specific requirement for usinguseRouter
.
useRouter()
vs Link
在 Next.js 中,useRouter
和 Link
都可以用于路由跳转,但它们在使用方式和适用场景上有所不同。下面是详细的对比:
useRouter()
useRouter
是一个 React hook,提供了对 Next.js 路由对象的访问。它允许你在函数组件中以编程方式进行导航.
useRouter
更加灵活。pathname
、query
等。Link
Link
是一个组件,专门用于在 Next.js 中创建导航链接。它使用 <a>
标签来渲染,提供了客户端路由,无需重新加载页面。
Link
更加简洁。Link
渲染为 <a>
标签,有助于搜索引擎优化。<a>
标签的所有属性和样式。useRouter
:适用于需要以编程方式进行导航的场景。Link
:适用于需要创建静态导航链接的场景。useRouter
:提供更多灵活性,可以根据逻辑动态生成路径。Link
:更简洁直观,适合简单的导航需求。Link
:渲染为 <a>
标签,有助于 SEO 和语义化。useRouter
:通常用于非链接的导航场景,不直接影响 SEO。Link
:代码更加简洁,适合在 JSX 中直接使用。useRouter
:需要编写事件处理函数,代码稍微复杂一些。redirect
函数import { redirect } from 'next/navigation'
async function fetchTeam(id: string) {
const res = await fetch('https://...')
if (!res.ok) return undefined
return res.json()
}
export default async function Profile({ params }: { params: { id: string } }) {
const team = await fetchTeam(params.id)
if (!team) {
redirect('/login')
}
// ...
}
Tips:
redirect
默认情况下返回 307(临时重定向)状态代码。在服务器操作中使用时,它会返回 303(请参阅其他),该 303 通常用于由于 POST 请求而重定向到成功页面。redirect
可能在内部报错,因此应在 try/catch
块外部调用它。redirect
;在用户交互事件中进行重定向,需要使用 useRouter
钩子。redirect
也接受 URL,可用于重定向到外部链接。next.config.js
或中间件。以上三种重定向方法(渲染前重定向、渲染时重定向和交互事件中重定向)在本质上都是为了将用户从一个路径重定向到另一个路径,但它们在执行时机、应用场景和技术实现上有所不同。下面是对这三种重定向的详细比较和解释:
执行时机: 在服务器接收到请求但在渲染页面之前进行重定向。 应用场景: 适用于需要在用户看到页面内容之前进行重定向的情况,例如:
next.config.js
的 redirects
方法:定义静态重定向规则。执行时机: 在客户端组件渲染期间进行重定向。 应用场景: 适用于需要在客户端组件渲染时根据某些条件进行重定向的情况,例如:
useRouter
钩子和 useEffect
进行重定向。执行时机: 在用户交互事件(如按钮点击、表单提交)中进行重定向。 应用场景: 适用于需要在特定用户交互事件触发后进行重定向的情况,例如:
useRouter
钩子在事件处理函数中进行重定向。这段话的意思是,在 Next.js
中,你可以使用浏览器的原生 window.history.pushState
和 window.history.replaceState
方法来更新浏览器的历史记录,而无需重新加载页面。同时,这些方法的调用会自动与 Next.js
的路由系统集成,从而保持与 usePathname
和 useSearchParams
钩子的同步。
使用原生方法更新历史记录
浏览器的 window.history.pushState
和 window.history.replaceState
方法允许你在不重新加载页面的情况下,更新浏览器的地址栏 URL 和历史记录。这在单页应用(SPA)中非常常见。 - pushState
:添加一个新的历史记录条目。 - replaceState
:替换当前的历史记录条目。
示例:
// 使用 pushState 添加新的历史记录条目
window.history.pushState({ page: 1 }, "title 1", "/page1");
// 使用 replaceState 替换当前的历史记录条目
window.history.replaceState({ page: 2 }, "title 2", "/page2");
集成到 Next.js 路由器
在 Next.js 中,当你使用 pushState
或 replaceState
方法时,这些操作会自动与 Next.js 的路由系统集成。这意味着你更新的 URL 会被 Next.js 识别并处理,就像你使用 Next.js 的路由器 API 一样。
App Router 使用混合方法进行路由和导航。在服务器上,应用程序代码会自动按路由段进行代码拆分。在客户端上,Next.js预取和缓存路由段。这意味着,当用户导航到新路由时,浏览器不会重新加载页面,只有更改的路段会重新呈现,从而改善导航体验和性能。
预取是一种在用户访问路由之前在后台预加载路由的方法。在 Next.js 中预取路由有两种方式:
<Link>
组件:当路由在用户视口中可见时,会自动预取路由。预取发生在页面首次加载或通过滚动进入视图时。useRouter.prefetch()
可用于以编程方式预取路由。<Link>
组件的默认预取行为(即,当 prefetch
属性未指定或设置为 null
时)会根据你是否使用了 loading.js
文件而有所不同。具体来说: loading.js
文件之间的组件树会被预取并缓存 30 秒。Next.js
有一个称为路由器缓存的内存中客户端缓存。当用户在应用程序中导航时,预取路由段和访问路由的 React Server 组件有效负载存储在缓存中。
这意味着在导航时,缓存会尽可能多地重复使用,而不是向服务器发出新请求 - 通过减少请求和传输的数据数量来提高性能。
部分渲染意味着仅在客户端上重新渲染导航时更改的路段,并且保留所有共享路段。
例如,在两个同级路由之间导航时, /dashboard/settings
/dashboard/analytics
将呈现 settings
和 analytics
页面,并保留共享 dashboard
布局。
硬导航(Hard Navigation):
软导航(Soft Navigation):
Next.js 的 App Router 支持软导航,这带来了以下好处:
默认情况下,Next.js将保持向后和向前导航的滚动位置,并在路由器缓存中重用路由段。