学习目标
- 1理解Next.js是什么,为什么它是TypeScript的最佳搭档
- 2掌握App Router的文件系统路由
- 3学会创建页面和布局
- 4理解服务器组件和客户端组件的区别
回顾与问题引入
在前面的章节中,我们已经掌握了TypeScript的核心能力:类型系统、接口、泛型、工具类型。你可能会问——学了这么多类型知识,怎么用到真实的网站里?
这就是本章要解决的问题。
想象一下:你已经设计好了博客的数据类型(Post、User、Comment),现在需要把这些类型变成一个真正能访问的网站。你需要:
- 一个首页展示文章列表
- 点击文章进入详情页
- 一个"写文章"的页面
传统的方式是:用一个前端框架(比如React)做页面,再用一个后端框架(比如Express)做API,分别部署。这就像开一家餐厅,厨房和餐厅要分两个地方——客人点餐要跑来跑去,效率很低。
Next.js就是那个"前厅后厨一体化"的解决方案。
Next.js是什么?
简单来说,Next.js是基于React的全栈框架。如果说React是一套"装修材料",那Next.js就是一套"精装房"——React能做的它都能做,还额外送你很多开箱即用的功能。
一个生活化的类比:
| 概念 | 类比 | |------|------| | React | 毛坯房(需要自己装修) | | Next.js | 精装房(拎包入住) | | 页面路由 | 房间的门牌号 | | 布局(Layout) | 每个房间都有的标配家具 | | API路由 | 房间里的服务按钮 |
Next.js的核心特性:
- 文件系统路由:文件路径就是网址,不需要手动配置
- 服务器端渲染(SSR):页面在服务器上生成,SEO友好
- 静态站点生成(SSG):提前生成页面,访问速度极快
- API路由:前后端写在一个项目里
- 自动代码分割:只加载当前页面需要的代码
- TypeScript原生支持:零配置就能用TS
创建Next.js项目
文件系统路由:路径即页面
这是Next.js最巧妙的设计之一:你创建的文件路径,就是网站的URL路径。
不需要写任何路由配置文件,不需要import路由库。你只需要在app目录下创建文件夹和文件,Next.js就会自动帮你搞定路由。
类比理解:
文件系统路由就像酒店的房间号系统:
app/page.tsx→ 大厅(首页/)app/about/page.tsx→/about房间app/blog/page.tsx→/blog房间app/blog/[slug]/page.tsx→/blog/xxx动态房间(每个客人不同)
关键规则:
- 每个
page.tsx文件代表一个页面 - 文件夹名就是URL路径段
[参数名]表示动态路由参数
页面和路由实战
布局(Layout):页面的共享外壳
每个网站都有一些所有页面共享的部分——比如导航栏、页脚、侧边栏。在Next.js中,这些共享部分叫做布局(Layout)。
类比理解:
布局就像相框:
- 相框的边框是固定的(导航栏、页脚)
- 相框里的照片可以换(页面内容)
- 你不需要每次都重新做相框
布局的特点:
- 在页面切换时不会重新渲染(保持状态)
- 可以嵌套(子页面有自己的布局)
- 是定义
<html>和<body>标签的地方
布局实战
服务器组件 vs 客户端组件:一个关键区别
这是Next.js 13+最重要的概念之一,也是很多人容易混淆的地方。
问题场景:
你写了一个页面,想在点击按钮时显示一个计数器。但页面报错了,提示你不能在服务器组件中使用useState。
为什么?
因为Next.js默认把所有组件当作服务器组件——它们在服务器上运行,不在用户的浏览器里。服务器组件不能做"交互"的事情(比如响应点击、管理状态)。
类比理解:
| 组件类型 | 类比 | 能做什么 | |----------|------|----------| | 服务器组件 | 厨房里的厨师 | 获取数据、渲染HTML、访问数据库 | | 客户端组件 | 餐厅里的服务员 | 响应用户操作、管理状态、使用浏览器API |
关键规则:
- 服务器组件:默认,可以直接
await获取数据 - 客户端组件:需要在文件顶部添加
"use client"指令 - 服务器组件不能使用useState、useEffect等Hook
- 客户端组件不能直接访问数据库
两种组件对比
常见错误
常见错误
错误1:在服务器组件中使用useState
// 错误!服务器组件不能用 useState
export default function Page() {
const [count, setCount] = useState(0); // 报错!
return <div>{count}</div>;
}
解决: 在文件顶部添加 "use client",或者把交互部分抽成客户端组件。
错误2:忘记page.tsx文件名
// 错误!app/about.tsx 不会创建 /about 路由
// 正确:app/about/page.tsx
解决: 每个路由目录下必须有 page.tsx 文件。
错误3:动态路由参数类型错误
// 错误!params 是对象,不是字符串
export default function Page({ params }: { params: string }) {}
// 正确
export default function Page({ params }: { params: { slug: string } }) {}
解决: 动态路由的params是一个对象,key是参数名。
错误4:在客户端组件中直接访问数据库
"use client";
import { db } from "@/lib/database"; // 客户端不能用这个!
// 解决:把数据获取放在服务器组件,通过props传递
动手实践
现在轮到你了!让我们动手练习:
练习1:创建一个用户个人资料页面
- 路径:
/users/[userId] - 显示用户ID
- 添加一个"返回首页"的链接
练习2:创建一个嵌套布局
- 在
/dashboard目录下创建布局 - 布局包含侧边栏和内容区
- 创建两个子页面:
/dashboard/settings和/dashboard/profile
练习3:区分服务器组件和客户端组件
- 创建一个服务器组件,显示当前时间(服务器时间)
- 创建一个客户端组件,显示一个计数器
- 思考:为什么"当前时间"适合用服务器组件?
提示:
- 服务器组件适合展示静态或服务器端数据
- 客户端组件适合需要用户交互的场景
- 可以在服务器组件中嵌套客户端组件
本章总结
恭喜你完成了Next.js基础的学习!让我们回顾一下:
本章学到的:
- Next.js是基于React的全栈框架,"前厅后厨一体化"
- 文件系统路由:文件路径即URL,不需要手动配置路由
- 布局(Layout):页面的"共享外壳",导航栏和页脚放在这里
- 服务器组件 vs 客户端组件:默认是服务器组件,交互需要"use client"
前后对比:
| 方面 | 之前(纯React) | 现在(Next.js) | |------|-----------------|-----------------| | 路由 | 需要react-router配置 | 文件路径即路由 | | 数据获取 | useEffect + fetch | 直接在组件中await | | SEO | 需要额外配置 | 开箱即用 | | 前后端 | 需要两个项目 | 一个项目搞定 |
下一章预告:
我们已经有了页面,但博客还需要后端API来管理文章数据。下一章我们将学习Next.js的API路由——如何在同一个项目中创建RESTful API,让前端和后端共享TypeScript类型。
交互式练习
创建Next.js页面
创建一个用户个人资料页面,接收userId参数
章节测验
Next.js默认使用什么类型的组件?