Table of contents
第一次了解到 Next.js
是在开源项目 nextjs-notion-starter-kit,同步也是用这个项目搭建了一个基于 notion
的博客平台并且部署到了 vercel 上。以及最近经常看到 Youtube
上很多前端的项目都是基于 next.js
做的。所以有必要学习一下这个框架。 通过 Next.js 官方文档的阅读,可以看到其中有很多的特性,内容丰富、功能强大,简化优化开发的过程。文章包括以下部分:
Project Structure
Router
Navigation
Pre-rendering
Data Fetching
API Route
Styling
Image
Typescript
What is Next.js
The React Framework for production
React
不太可能创建一个功能丰富的应用程序,用来部署到生产环境上
React 是一个用于构建用户界面的库
需要去为应用的其他特性如路由、样式、权限等再去添加一些额外的内容
Next.js
一个使用 React 构建用户界面的包
自动加载了很多的特性帮助你构建一个丰富的应用程序。特性包含路由、样式、权限、
bundle
的优化等不需要安装额外的包,
Next.js
提供了一切为了实现上述特性,需要遵循一些意见和惯例
Why learn Next.js
Next.js
简化了构建一个生产环境的 React
应用
File based routing
- 基于文件的路由Pre-rendering
- 预渲染API
路由支持
CSS modules
Authentication
- 认证Dev and Prod build system
- 开发和生产构建系统
Install Next.js App
可以使用下面的命令安装 Next.js
应用
npx create-next-app@latest --typescript
或者查看官方文档其他方式
Project Structure
需注意的是在 Next.js 中 pages 文件夹下的文件会自动生成路由,这部分会在下面介绍到。项目其他目录结构与别的脚手架没有什么大的不同
Route
在 React 应用中使用路由
需要安装第三方包
需要手动写文件去配置路由
每一个路由、每一个组件、都需要去配置路由的属性,比较麻烦
在 Next.js 应用中使用路由
基于文件系统的路由机制
当在项目中的
pages
目录下添加了一个文件,就会自动的变成一个可用的路由通过将文件名和嵌套文件夹结构混合和匹配,几乎可以定义最常见的路由模式
Routing with pages
NextJS
有个一个基于文件系统的路由器,建立在 pages 文件夹的概念上
当一个文件被添加到 pages
目录下时,就会自动相对应的生成可使用的路由
Scenario 1 root router
只需将 pages → index.tsx 中的内容修改为 Home Page 即可
Scenario 2 basic router
实现方式有两种
在
pages
目录下创建about.tsx
和profile.tsx
在
pages
目录下创建about
和profile
文件夹;再在两个文件夹中分别创建index.tsx
❗需要注意的是区分大小写
Scenario 3 Nested Routes
嵌套路由也就是文件夹的嵌套,实现方式还是两种,同上
在 pages
目录下先创建 blog
目录
first
和 second
可以是文件夹其中包含 index.tsx
文件;也可以是 first.tsx
和 second.tsx
Scenario 4 Dynamic Routes
存在 product
列表页和 Product
详情页,地址栏中的 id
是会发生变化的,是动态的
首先实现 product
列表页很简单,在 pages
目录下创建 product
目录 → index.tsx
文件
重点:动态 id
只需要将文件名用中括号包裹起来即可,如 [productId].tsx
。在 product
目录下创建 [productId].tsx
文件,然后在地址栏中输入 http://localhost:3000/product/1
,就会出现 [productId].tsx
组件中的内容。
组价内容根据 productId
动态展示的话可以通过 useRouter
获取路由信息
import React from "react";
import { useRouter } from "next/router";
export default function ProductDetail() {
const { query } = useRouter();
const productId = query.productId;
return (
<>
<h1>ProductDetail {productId} Page</h1>
</>
);
}
额外:如果在 product
目录下存在了 sweater.tsx
文件,地址栏输入的是http://localhost:3000/product/sweater
,那么展示的内容是哪个组件里的呢,答案是sweater.tsx
Scenario 5 Nested Dynamic Routes
这个场景就是 productId 是动态的,并且 reviewId 也是动态的
在
product
目录下创建[productId]
目录[productId]
目录下创建review
目录review
目录下创建动态的reviewId
文件
// index.tsx 就是上一个场景中的 [productId].tsx的内容
// [reviewId].tsx
import React from "react";
import { useRouter } from "next/router";
export default function ReviewDetail() {
const { query } = useRouter();
const { productId, reviewId } = query;
return (
<>
<h1>
Review {reviewId} for product {productId}
</h1>
</>
);
}
Scenario 6 Catch all routes
如图有这样的文档页面,比如有文档中有20个特性,每个特性又有20个概念,那么就会有400个路由,这种该怎么实现呢。
如果要获取地址栏 docs
后面的内容,不论后面的内容嵌套了多少层,只需要创建 […params].tsx
即可。此时通过 useRouter
获取参数时会返回一个对象,对象的值是数组。而非之前单个的字符串了。
import React from "react";
import { useRouter } from "next/router";
export default function DocsDetail() {
const { query } = useRouter();
const { params } = query;
return (
<>
{params &&
Array.isArray(params) &&
params.map((item) => {
return <h1 key={item}>{item}</h1>;
})}
<h1>DocsDetail Page</h1>
</>
);
}
此时如果地址栏是http://localhost:3000/docs
时,由于没有在 docs
目录下创建 index.tsx
文件,页面会报 404。修改这个问题有两种方法:
添加
index.tsx
文件将
[…params].tsx
修改为[[…params]].tsx
即可
Navigation
路由有了,就需要在路由之间的跳转。那么跳转的方式有两种
使用
Link
组件使用
useRouter
Link Component Navigation
使用 NextJS
提供的 Link
组件,可以很方便的跳转
import Link from "next/link";
<Link href="/blog">Blog Page</Link>
Link
组件中传入 href
属性,值为对应的路由地址
注意:在新版本中不要在 Link
组件中添加 a
标签,具体查看官方文档
Link
中还可以传 replace
属性 ,replace 会替换当前浏览器的历史状态而不是再添加一个新的 url
Navigating Programmatically
如图我们需要点击 PlaceOrder
按钮,跳转到 product
页面
这种情况下就需要用到 useRouter
,而不是 Link
组件了
import Link from "next/link";
import { useRouter } from "next/router";
export default function Home() {
const router = useRouter();
const handleGoProduct = () => {
router.push("/product");
};
return (
<>
<div>
<button onClick={handleGoProduct}>Place Order</button>
</div>
</>
);
}
同时 router
也有 replace
方法,效果与 Link
中的 replace
相同
Custom 404 Page
路由总会有不匹配的时候,NextJS
给我们提供一个 404
页面,但是如果我们想自定义 404
页面时,只需要在 pages
目录下创建一个 404.tsx
组件进行修改即可。
第一部分就先介绍这些
内容及图片均来自 Youtube CodeVolution