Next.js学习笔记
Posted at 2025-10-28
杂
next的一些convention
- 每一个页面都可以定义其单独的meta data,如浏览器标签页会显示的title
- 在app文件夹下直接放一个名字为
icon.*的图片文件,即可将其作为网页的favicon - 项目根目录下放一个
middleware.js,可以作为request和response之间的中间件
字体优化
next/font 本质上是将复杂的性能优化工作自动化了。你只需要像调用 JS 函数一样引入字体,它就能帮你搞定自托管、子集化和防布局抖动(CLS)。
使用方式:
// app/layout.js 或类似的组件文件
import { Inter } from 'next/font/google';
// 配置字体
const inter = Inter({
subsets: ['latin'],
display: 'swap', // 优秀的性能实践:字体下载前先显示后备字体
});
export default function RootLayout({ children }) {
return (
<html lang="en">
{/* 1. 直接应用 class 到 body */}
<body className={inter.className}>
{children}
</body>
</html>
);
}图片加载优化
使用next/image提供的Image组件,自动集成懒加载、防布局抖动、按需优化、解码适配等等
- src为网络url时,要求提供width属性
错误边界
- 文件名约定:
error.js为错误边界组件,自动应用到对应的app route中 - 错误边界必须声明为"use client",自动接收{error, reset}作为props,用于显示错误信息、提供reset按钮
登陆鉴权
- 使用next-auth库
一些概念
react SPA 🆚 next.js SSR
SPA:
在客户端渲染页面
适合复杂交互,有特定用户群体
需要下载所有的js包使网页运作
SSR (Server side render):
在服务端渲染页面
良好的SEO!首屏加载快

Next.js四大要素
- SSR(静态&动态)
- 独特的Router : "App"Router
- 服务端的数据获取与修改
- 优化: 图片、SEO、字体、ect。。
路由App Router与layout
- 根据文件夹配置路由,路由index页面文件遵守命名规范:
page.tsx- 如果不希望该文件夹是一个页面,可加_前缀。如
_component
- 如果不希望该文件夹是一个页面,可加_前缀。如
Link组件 layout- layout组件接受children prop渲染子组件 动态字段路由
/cabins/${cabinId}在父路由的文件夹下,建立一个[cabinId]文件夹,里面的Page.js组件会自动接收一个名为params的props,可用params.cabinId获取动态路由字段的值
数据获取与渲染
动态&静态 渲染
针对路由route的概念,反映一个路由是“动态的”or“静态的”
静态渲染
适用场景
- 适用于静态展示”PPT“,由开发者决定渲染的内容 特点
- Next.js默认使用静态SSR
- 提前渲染好,访问更快
- “更新”静态内容的三个方式:
- 重新构建
- ISR(增量静态再生),根据时间自动重新验证。
revalidate: 60 - 事件驱动:按需重新验证。 用到
revalidateTag或revalidatePath
动态渲染
不要缓存这个页面的任何数据,也不要持久化它的 HTML,每次请求都请重新计算 适用场景
- 适用于数据更改频繁或用户状态自定义内容,由用户决定渲染的内容
触发条件(若满足条件,next.js会自动将路由变为动态渲染):
- 路由page使用了url中的动态字段参数或者查询参数
- 路由下任一Server component使用了
headers()或者cookies(),如受auth影响的page - 路由下任一Server component发生未被缓存的请求(是否有 fetch 指明
no-store? → 是 → 动态渲染。) - 显式声明
export const dynamic = 'force-dynamic';
混合渲染
动静结合,静态外壳(static shell)中,静态内容立即发送,动态内容流式传输 使用方法:
- 利用 Suspense 定义边界
缓存

🌟Client & Server
RSC
react server component
- 使用client component时,代码第一行写
'use client;'
- SC无状态,CC有状态
- 默认优先: 始终先尝试用 Server Component。只有当发现“哎呀,我需要用户点个按钮”或者“我需要监听滚动”时,才考虑把那一小块抽离成 Client Component。
client & server 组件
| 方向 | 是否允许 | 实现方式 |
|---|---|---|
| Server -> Client | ✅ 允许 | 传递 Props 或 使用 children 组合。 |
| Client -> Server | ❌ 禁止 | 不能直接 import 服务端逻辑。 |
| Client -> Server (交互) | ✅ 允许 | 使用 Server Actions (一种特殊的加密 HTTP POST 请求)。 |
- ==client向server传递数据的方式 : 通过路由URL传递==
Server Action
文件开头声明"use server",这个文件export的函数(async function)就成为了server action
- server action 可以增删改数据(mutation)
- 通过事件驱动(
revalidateTag或revalidatePath)来更新UI
useFormStatus :一个可以获取form状态的hook
useFransition: const [isPending, startTransition] = useTransition();
useOptimistic: 用于乐观更新
useOptimistic doesn't poll or watch anything. It simply:
- Applies the optimistic update immediately
- Holds it until the wrapping async action completes
- Discards it on success (real state takes over)
- Reverts it on failure (thrown error)
startTransition(async fn) 和 <form action> 都是告诉 React "帮我管理这个异步操作"的方式。脱离这两者,useOptimistic 就失去了自动 revert 的能力。