Next13
[TOC]
什么是Next
Next.js 是一个React框架,支持CSR、SSR、SSG、ISR (Incremental Static Regeneration)等渲染模式。
Next.js 提供了创建 Web 应用程序的构建块,比如:
- 用户界面、路由、数据获取、渲染模式、后端服务等等
Next.js 不但处理 React 所需的工具和配置,还提供额外的功能和优化,比如:
- UI构建, CSR、SSR、SSG、ISR 渲染模式,Routing、Data Fetching等等。
中文官网:https://www.nextjs.cn/docs/getting-started
英文官网:https://nextjs.org/docs/getting-started
Next.js 发展史
Next.js 于2016 年 10 月 25 日首次作为开源项目发布在GitHub上,最初是基于六个原则开发的:
- 开箱即用、无处不在的JS、所有函数用JS编写、自动代码拆分和服务器渲染、可配置数据获取、预期请求和简化部署。
Next.js 2.0 于 2017 年 3 月发布,改进后的版本让小型网站的工作变得更加容易,还提高了构建和热模块替换效率。
7.0 版于 2018 年 9 月发布,改进了错误处理并支持 React 的上下文 API。升级到了webpack4
8.0 版于 2019 年 2 月发布,第一个提供 Serverless 部署的版本。
2020 年 3 月发布的 9.3 版包括各种优化和全局Sass和 CSS 模块支持。
2020 年 7 月 27 日,Next.js 9.5 版发布,增加了增量静态再生成、重写和重定向支持等新功能。
2021 年 6 月 15 日,Next.js 版本 11 发布,其中包括:Webpack 5 支持
2021 年 10 月 26 日,Next.js 12 发布,添加了 Rust 编译器,使编译速度更快
2022 年 10 月 26 日,Vercel 发布了 Next.js 13。
- 带来了一种新的路由模式,增加了app目录 、布局布局、服务器组件和一组新的数据获取方法等(目前是 beta 版本)
- 编译和压缩等由 Babel + Terser 换为 SWC( Speedy Web Compiler ),构建工具增加了 Turbopack。
Next.js 特点
开箱即用,快速创建:
- Next.js 已经帮我集成好了各种技术栈,比如:React、webpack、路由、数据获取、SCSS、TypeScript等等
- 也提供了专门的脚手架:create-next-app
约定式路由(目录结构即路由)
- Next.js和Nuxt3一样,所有的路由都是根据 pages目录结构自动生成。但在 Next.js 13 beta 版本增加了app目录。
内置CSS模块和Sass支持:
- 自从Next.js 9.3 以后就内置了CSS模块和Sass支持,也是开箱即用
全栈开发能力:
- Next.js不但支持前端开发,还支持编写后端代码,比如:可开发登录验证、存储数据、获取数据等接口
多种渲染模式:支持CSR、SSR、SSG、ISR等渲染模式,当然也支持混合搭配使用
利于搜索引擎优化:
- Next.js支持使用服务器端渲染,同时它也是一个很棒的静态站点生成器,非常利于SEO和首屏渲染
Next.js VS Nuxt3
Next.js 和 Nuxt3的相同点
- 利于搜索引擎优化,都能提高首屏渲染速度
- 零配置,开箱即用
- 都支持目录结构即路由、支持数据获取、支持TypeScript
- 服务器端渲染、静态网站生成、客户端渲染等
- 都需要 Node.js 服务器,支持全栈开发
Next.js 和 Nuxt3区别:
- Next.js 使用的是React技术栈:React 、webpack 、express 、node.....
- Nuxt3 使用的是Vue技术栈:Vue、webpack、vite、h3、nitro、node.....
- Nuxt3 支持组件、组合 API、Vue API等自动导入,Next.js则不支持
- Next.js 社区生态、资源和文档都会比Nuxt3友好(star数: Nuxt3 -> 41.6k 和 Next.js -> 96.8k )
Next.js 和 Nuxt3如何选择? 个人建议如下:
- 首先根据自己擅长的技术栈来选择,擅长Vue选择Nuxt3,擅长React选择Next.js
- 需要更灵活的,选择Next.js
- 需要简单易用、快速上手的,选择Nuxt3
Next.js 13 环境搭建
在开始之前,请确保您已安装推荐的设置:
- Node.js (要求 Node.js 14.6.0 或 更高版本。 )
- Git(window下可以用其随附的 Git Bash 终端命令)
- Visual Studio Code
创建一个项目,项目名不支持大写
- 方式一:
npx create-next-app@latest --typescript
- 方式二:
yarn create next-app --typescript
- 方式三:
pnpm create next-app –typescript
- 方式四:
npm i create-next-app@latest –g && create-next-app
运行项目
npm run dev
yarn dev
pnpm dev
Next.js 目录结构
入口App组件(_app.tsx)
_app.tsx是项目的入口组件,主要作用:
- 可以扩展自定义的布局(Layout)
- 引入全局的样式文件
- 引入Redux状态管理
- 引入主题组件等等
- 全局监听客户端路由的切换
ts.config.json 的配置
Next.js默认是没有配置路径别名的,我们可以在ts.config.json中配置模块导入的别名:
- baseUrl :配置允许直接从项目的根目录导入,比如:
import Button from 'components/button'
- paths:允许配置模块别,比如:
import Button from '@/components/button'
注意:如生效可以重启编辑器
环境变量(.env*)
定义环境变量的4种方式:
.env
:所有环境下生效的默认设置.env.development
:执行 next dev 时加载并生效.env.production
: 执行 next start 时加载并生效.env.local
:始终覆盖上面文件定义的默认值。所有环境生效,通常只需一个.env.local
文件就够了(常用存储敏感信息)
环境变量定义语法(支持变量,例如 $PORT):
- 大写单词,多个单词使用下划线,比如:
DB_HOST=localhost
- 添加 NEXT_PUBLIC_ 前缀会额外暴露给浏览器,比如:
NEXT_PUBLIC_ANALYTICS_ID=aaabbbccc
环境变量的获取:
- .env 文件中定义环境变量会加载到 process.env 中。两端都可直接通过
process.env.xxx
访问使用(不支持解构)
注意事项:
- 由于 .env、.env.development 和 .env.production 文件定义了默认设置,需提交到源码仓库中。
- 而 .env.*.local 应当添加到 .gitignore 中,因为这类文件是需要被忽略的。
Next.js配置(next.config)
next.config.ts 配置文件位于项目根目录,可对Next.js进行自定义配置,比如,可以进行如下配置:
- reactStrictMode: 是否启用严格模式,辅助开发,避免常见错误,例如:可以检查过期API来逐步升级
- env:配置环境变量,配置完需要重启
- 会添加到 process.env.xx 中
- 配置的优先级: next.config.js中的env > .env.local > .env
- basePath:要在域名的子路径下部署 Next.js 应用程序,您可以使用basePath配置选项。
- basePath:允许为应用程序设置URl路径前缀。
- 例如 basePath=/music, 即用 /music 访问首页,而不是默认 /
- images:可以配置图片URL的白名单等信息
- swcMinify: 用 Speedy Web Compiler 编译和压缩技术,而不是 Babel + Terser 技术
更多的配置: https://nextjs.org/docs/api-reference/next.config.js/introduction
内置组件
Next.js框架也提供了几个内置组件,常用的有:
- Head:用于将新增的标签添加到页面的 head 标签中,需要从 next/head 中导入
- 如果想要给所有页面统一添加的,那需在pages目录下新建 _document.js 文件来定制HTML页面
- Script:将一个script标签到页面的 body 中(不支持在_document.js 中用),需要从 next/script 中导入
- Link:可以启用客户端的路由切换,需从 next/link 导入
- Image:内置的图片组件(对 img 的增强)。需从 next/image 导入
Image组件
Image:内置的图片组件,是对 img 的增强,需从 next/image 导入。
Image组件常用属性
- src 属性:
- 引入本地图片资源,会自动确认图片的宽高,
- 引入外部资源需,需手动给宽高,还需配置白名单。
- width/height:是 number 类型,不支持100%等字符串
- priority:将图片标记为 LCP ( Largest Contentful Paint )元素,允许预加载图像。
- 建议大图,并在首屏可见时才应使用该属性。默认为 false
- placeholder:图片占位,默认值为empty,当值为blur需和blurDataURL一起用
- fill :让图片填充父容器大小,父容器需设为相对定位
全局和局部样式
Next.js 允许在 JavaScript 文件中直接通过 import 关键字来导入CSS 文件(不是:@import )
全局样式:
- 在 assets 目录或 styles 目录下编写,然后在
pages/_app.js
入口组件中导入 - 也支持导入
node_modules
中样式,导入文件后缀名不能省略
局部样式:
- Next.js 默认是支持 CSS Module的,如:
[name].module.css
- CSS Module 中的选择器会自动创建一个唯一的类名。
- 唯一类名保证在不同的文件中使用相同CSS类名,也不用担心冲突
内置Scss支持
- 用 scss 之前,需安装Sass:
npm i sass –D
- xx.module.scss文件
:export
中定义的变量,可导出供JavaScript中用
静态资源引用
public目录
- 常用于存放静态文件,例如:robots.txt、favicon.ico、img等,并直接对外提供访问。
- 访问需以 / 作为开始路径,例如:添加了一张图片到 public/me.png中
- 可通过静态URL: /me.png 访问,如右图
- 静态URL也支持在背景中使用
- 注意: 确保静态文件中没有与 pages/ 下的文件重名,否则导致错误。
assets目录
- 常用存放样式、字体 、图片或 SVG 等文件
- 可用 import 导入 位于assets目录的文件,支持相对路径和绝对路径
import Avatar from “../assets/images/avatar.png”
import Avatar from “@/assets/images/avatar.png”
- 背景图片和字体:
url("~/assets/images/bym.png")
字体图标
字体图标使用步骤
- 1.将字体图标存放在 assets 目录下
- 2.字体文件可以使用相对路径和绝对路径引用。
- 3.在_app.tsx文件中导入全局样式
- 4.在页面中就可以使用字体图标了
新建页面
Next.js项目页面需在pages目录下新建( .js, .jsx, .ts, or .tsx )文件,该文件需导出的React组件。
Next.js 会根据 pages 目录结构和文件名,来自动生成路由,比如:
pages/index.jsx
→/
(首页, 一级路由)pages/about.jsx
→/about
(一级路由)pages/blog/index.jsx
→/blog
(一级路由)pages/blog/post.jsx
→/blog/post
(嵌套路由,一级路由)pages/blog/[slug].jsx
→/blog/:slug
(动态路由, 一级路由)
新建页面步骤:
- 1.新建一个命名为
pages/about.jsx
组件文件,并导出(export)React 组件。 - 2.接着通过
/about
路径,就可访问新创建的页面了。
注意:Nuxt3 需要添加<NuxtPage>
内置组件占位, Next.js则不需要
组件导航(Link)
页面之间的跳转需要用到<Link>
组件,需从 next/link 包导入。
Link组件底层实现是一个 <a>
标签,所以使用 a + href 也支持页面切换(不推荐, 会默认刷新浏览器)
<Link>
组件属性:
- href 值类型(不支持 to)
- 字符类型:
/
、/home
、/about
- 对象类型:
{ pathname:’’ , query : { } }
- URL:外部网址
- 字符类型:
- as:在浏览器的 URL 栏中显示的路径的别名。
- replace:替换当前url页面,而不是将新的 url 添加到堆栈中。默认为 false
- target:和a标签的target一样,指定何种方式显示新页面
编程导航 (useRouter)
Next13除了可以通过<Link>
组件来实现导航,同时也支持使用编程导航。
编程导航可以轻松的实现动态导航了,缺点就是不利于SEO。
我们可以从 next/router 中导入 useRouter 函数(或 class 中用 withRouer),调用该函数可以拿到 router对象进行编程导航。
router 对象的方法:
- push( url [, as , opts] ) :页面跳转
- replace( url [, as , opts] ) :页面跳转(会替换当前页面)
- back():页面返回
- events.on(name, func):客户端路由的监听(建议在_app.tsx监听)
- routeChangeStart
- routeChangeComplete
- beforePopState :路由的返回和前进的监听。 (建议在_app.tsx监听)
- ....
动态路由
Next.js也是支持动态路由,并且也是根据目录结构和文件的名称自动生成。
动态路由语法:
- 页面组件目录 或 页面组件文件都 支持 [ ] 方括号语法(方括号前后不能有字符串)。
- 方括号里编写的字符串就是:动态路由的参数。
例如,动态路由 支持如下写法:
pages/detail/[id].tsx -> /detail/:id
pages/detail/[role]/[id].tsx -> /detail/:role/:id
pages/detail-[role]/[id].tsx -> /detail-:role/:id
路由参数(useRouter)
动态路由参数
- 1.通过 [] 方括号 语法定义动态路由,比如:/post/[id].tsx
- 2.页面跳转时,在URL路径中传递动态路由参数,比如:/post/10010
- 3.动态路由参数将作为查询参数发送到目标页面,并与其他查询参数合并
- 4.目标页面通过 router.query 获取动态路由参数(注意:Next.js 是 router, Nuxt3 是 route)
查询字符串参数
- 1.页面跳转时,通过查询字符串方式传递参数,比如:
/post/10010?name=liujun
- 2.目标页面通过 router.query 获取查询字符串参数
- 3.如果路由参数和查询参数相同,那么 路由参数 将覆盖同名的 查询参数。
404 Page
方式一:捕获所有不匹配的路由(即 404 not found 页面)
- 通过在方括号内添加三个点 ,如:
[...slug].tsx
语法,如在其它目录下的话,仅作用于该目录以及子目录- 比如:访问
pages/post/[...slug].js
路径,将匹配/post/a 、/post/a/b、/post/a/b/c等,但不匹配 /post - 注意:是可以使用除了slug以外的名称,例如:
[...param].tsx
- 比如:访问
- [...slug] 匹配的参数将作为查询参数发送到页面,并且它始终是一个数组
- 如: 访问 /post/a 路径,对应的参数为:
{ "slug": ["a"] }
- 如:访问 /post/a/b 路径,对应的参数为:
{ "slug": ["a", "b"] }
- 如: 访问 /post/a 路径,对应的参数为:
方式二(推荐):在 pages 根目录新建 404.tsx 页面(注意:只支持根目录)
- 当然还支持 500.tsx 文件,即客户端或者服务器端报错
路由匹配规则
路由匹配优先级, 即预定义路由优先于动态路由,动态路由优先于捕获所有路由。请看以下示例:
- 1.预定义路由:pages/post/create.js
- 将匹配 /post/create
- 2.动态路由 :pages/post/[pid].js
- 将匹配/post/1, /post/abc 等。
- 但不匹配 /post/create 、 /post/1/1 等
- 3.捕获所有路由:pages/post/[...slug].js
- 将匹配 /post/1/2, /post/a/b/c 等。
- 但不匹配/post/create, /post/abc、/post/1、、/post/ 等
中间件(middleware)
Next.js的中间件允许我们去拦截客户端发起的请求,例如:API请求、router切换、资源加载、站点图片等。
拦截客服端发起的请求等等之后,便可对这些进行:重写、重定向、修改请求响应标头、或响应等操作。
使用中间件需按照以下步骤操作:
- 1.在根目录中创建 middleware.ts 文件
- 2.从 middleware.ts 文件中导出一个中间件middleware函数(支持 async,并只允许在服务端),会接收两个参数:
- req:类型为 NextRequest
- event:类型为 NextFetchEvent
- 3.通过返回NextResponse对象来实现重定向等功能
- next()- 将继续中间件链
- redirect()- 将重定向,如:重定向到某个页面
- rewrite()- 将重写URL,如:配置反向代理
- 4.没返回值:页面将按预期加载 和 返回 next() 一样
匹配器(Matcher)
匹配器允许我们过滤中间件以在特定路径上运行,比如:
matcher: ‘/about/:path*
, 意思是匹配以/about/*
开头的路径。其中路径开头的:是修饰符, 而 * 代表0个 或 n个matcher: [‘/about/:path*’, ‘/dashboard/:path*’]
, 意思是匹配以/about/*
和/dashboard/*
开头的路径 -matcher: [‘/((?!api|_next/static|favicon.ico).*)‘]
,意思是不匹配以 api、_next、static、favicon.ico 开头的路径
注意:上面的 path 是占位符, 不是固定的。
路由拦截
下面我们通过 中间件 + 匹配器 来实现路由的拦截:
matcher: ['/((?!api|_next/static|favicon.ico).*)']
布局组件(Layout)
Layout布局是页面的包装器,可以将多个页面的共性东西写到Layout布局中,使用 props.children 属性来显示页面内容
- 例如:每个页面的页眉和页脚组件,这些具有共性的组件我们是可以写到一个Layout布局中。
Layout布局的使用步骤:
- 1.在components目录下新建 layout.tsx 布局组件
- 2.接着在_app.tsx中通过
<Layout>
组件包裹<Component>
组件
嵌套布局(NestLayout)
Layout布局可以作为所有页面的容器,也可以给每个页面一个单独的布局也是可以的,并且也可以在布局中嵌套布局。
因此,我们可以利用布局再嵌套一个布局来实现二级路由。
嵌套路由
Next.js 和 Nuxt3一样,也支持嵌套路由(但是只在app目录下),也是根据目录结构和文件的名称自动生成。
二级路由实现有两种方案:
- 方案一:使用Layout布局嵌套来实现
- 方案二:使用Next.js 13版本,新增的app目录(目前 beta 版本)
App目录和布局
Next.js 13版本,新增的app目录(目前 beta 版本,还是处于实验性阶段,需要在配置开始)
第一步:创建app目录
第二步:创建根HTML布局:layout.tsx
第三步:创建首页: page.tsx
第四步:创建head.tsx,定制head
第五步:创建其它页面和布局
- page.tsx
- layout.tsx
组件生命周期
客户端渲染
服务器端渲染
- constructor
- UNSAFE_componentWillMount
- render -> functon component 本身
axios封装
安装依赖库
npm i axios –save
封装axios步骤
- 1.定义HYRequest类,并导出
- 2.在类中定义request、get、post方法
- 3.在request中使用axios发起网络请求
- 4.添加TypeScript类型声明
API Routes
Next.js 提供了编写后端接口的功能(即 API Routes),编写接口可以在 pages/api
目录下编写
在 pages/api 目录下的任何 API Routes 文件都会自动映射到以 /api/*
前缀开头接口地址
比如:编写一个 /api/user 接口
- 1.在 pages/api 目录下新建 user.ts
- 2.接在在该文件中使用 handler 函数来定义接口
- 3.然后就可以用 fetch 函数 或 axios 轻松调用: /api/user 接口了
认识预渲染
认识预渲染
- 默认情况下,Next.js 会 预渲染 每个页面,即预先为每个页面生成 HTML 文件,而不是由客户端 JavaScript 来完成。
- 预渲染可以带来更好的性能和 SEO 效果。
- 当浏览器加载一个页面时,页面依赖JS代码将会执行,执行JS代码后会激活页面,使页面具有交互性。(此过程称Hydration)
Next.js 具有两种形式的预渲染:
- 静态生成 (推荐):HTML 在 构建时 生成,并在每次页面请求(request)时重用。
- 服务器端渲染:在 每次页面请求(request)时 重新生成 HTML页面。
提示:出于性能考虑,相对服务器端渲染,更 推荐 使用 静态生成 。
SSG-静态生成(一)
静态生成(也称SSG 或 静态站点生成)
- 如果一个页面使用了 静态生成,在 构建时 将生成此页面对应的 HTML 文件 。这意味着在生产环境中,运行 next build 时将生成该 页面对应的 HTML 文件。然后,此 HTML 文件将在每个页面请求时被重用,还可以被 CDN 缓存。
- 在 Next.js 中,你可以静态生成 带有或不带有数据 的页面。接下来我们分别看看这两种情况。
生成不带数据的静态页面
- 默认情况下,Next.js 使用 “静态生成” 来预渲染页面但不涉及获取数据。如下例所示:
- 请注意:
- 此页面在预渲染时不需要获取任何外部数据。
- 在这种情况下,Next.js 只需在构建时为每个页面生成一个 HTML 文件即可。
SSG-静态生成(二)
需要获取数据的静态页面生成
- 当某些页面需要获取外部数据以进行预渲染,通常有两种情况:
- 情况一:页面 内容 取决于外部数据:使用 Next.js 提供的 getStaticProps 函数。
- 情况二:页面 paths(路径) 取决于外部数据:使用Next.js 提供的 getStaticPaths 函数(通常还要同时用 getStaticProps)。
情况一:页面 内容 取决于外部数据
- 比如,发起网络请求拿到页面书籍列表的数据,并展示。
- 具体的使用步骤是:
- 1.先在getStaticProps函数中借助axios获取到数据
- 2.拿到异步数据之后 return 给页面组件
- 3.页面就可通过props拿到数据来渲染页面
- 4.在build时,经过以上步骤,一个静态页面就打包生成
SSG-静态生成(三)
情况二:页面 paths(路径) 取决于外部数据
- 例如,新建一个动态路由页面,然后发起网络请求拿到书本列表,然后每本书的信息都使用单独详情页面显示。
- 简单的理解就是,在build 阶段时,动态拿到n本书,然后根据n书动态生成n个静态详情页面。
静态生成应用场景
建议尽可能使用静态生成(无论有 与 没有数据),因为静态生成的页面可以构建一次,并可由 CDN 提供服。
我们可以为多种类型的页面使用静态生成,包括:
- 营销页面、官网网站
- 博客文章、投资组合
- 电子商务产品列表、帮助和文档
如果在用户请求之前就可以预渲染页面,那么应该选择静态生成。反之,静态生成就不合适了。
例如,页面要显示经常更新的数据,并且页面内容会在每次请求时发生变化,这时可以这样选择:
- 静态生成与客户端数据获取结合使用:
- 我们可以跳过预呈现页面的某些部分,然后使用客户端 JS 来填充它们,但是客户端渲染是不利于SEO优化的,例如:
- 在useEffect 中获取数据,在客户端动态渲染页面。
- 我们可以跳过预呈现页面的某些部分,然后使用客户端 JS 来填充它们,但是客户端渲染是不利于SEO优化的,例如:
- 服务器端呈现(也称动态呈现):
- Next.js 会根据每个请求预呈现一个页面。缺点是稍微慢一点,因为页面无法被 CDN 缓存,但预渲染页面将始终是最新的。
服务器端渲染(SSR)
服务器端渲染(也称SSR 或 动态渲染)
- 如果页面使用的是 服务器端渲染,则会在 每次页面请求时 重新生成页面的 HTML 。
- 要对页面使用服务器端渲染,你需要 export 一个名为 getServerSideProps 的 async 函数。
- 服务器将在每次页面请求时调用此函数。
例如,假设你的某个页面需要预渲染频繁更新的数据(从外部 API 获取)。你就可以编写 getServerSideProps 获取该数据并将 其传递给 Page ,如下所示:
服务器端渲染(注意事项)
我们知道getStaticProps和getStaticPaths函数都是在build阶段运行,那么getServerSideProps函数的运行时机是怎么样的呢?
getServerSideProps运行时机:
- 首先,getServerSideProps仅在服务器端运行,从不在浏览器上运行。
- 如果页面使用 getServerSideProps,则:
- 当直接通过URL请求此页面时,getServerSideProps在请求时运行,并且此页面将使用返回的 props 进行预渲染
- 当通过 Link 或 router切换页面来请求此页面时,Next.js 向服务器发送 API 请求,服务器端会运行getServerSideProps
什么时候该使用getServerSideProps?
- 当页面显示的数据必须在请求时获取的,才应使用getServerSideProps 。
- 如:页面需要显示经常更新的数据,并且页面内容会在每次请求时发生变化。
- 如过页面使用了getServerSideProps函数,那么该页面将在客户端请求时,会在服务器端渲染,页面默认不会缓存。
- 如果不需要在客户端每次请求时获取页面数据,那么应该考虑在 客户端动态渲染 或 getStaticProps.
增量静态再成(ISR)
Next.js 除了支持静态生成 和 服务器端渲染,Next.js 还允许在构建网站后创建或更新静态页面。
这种模式称为:增量静态再生(Incremental Static Regeneration),简称(ISR)。
比如我们继续实现前面的案例:
- 发起网络请求拿到页面书籍列表的数据,并展示。这次我们使用ISR渲染模式,让服务器端每隔5s重新生成静态书籍列表页面
客户端渲染(CSR)
Next.js 除了支持在服务器端获取数据,同时也是支持在客户端获取数据,并在客户端进行渲染。
在客户端获取数据,需要在页面组件或普通组件的 useEffect 函数中获取,比如:
Next.js 集成 Redux
安装依赖库
npm i next-redux-wrapper --save
- 可以避免在访问服务器端渲染页面时store的重置
- 该库可以将服务器端redux存的数据,同步一份到客户端上
- 该库提供了HYDRATE调度操作
- 当用户访问动态路由或后端渲染的页面时,会执行Hydration来保持两端数据状态一致
- 比如:每次当用户打开使用了getStaticProps或getServerSideProps函数生成的页面时,HYDRATE将执行调度操作。
npm i @reduxjs/toolkit react-redux --save
创建counter模块的reducer
我们先创建counter模块的reducer: 通过createSlice创建一个slice。
createSlice主要包含如下几个参数:
- name:用来标记slice的名词
- redux-devtool中会显示对应的名词;
- initialState:第一次初始化时的值;
- reducers:相当于之前的reducer函数
- 对象类型,并且可以添加很多的函数;
- 函数类似于 redux 原来reducer中的一个case语句;
- extraReducer:添加更多额外reducer处理other action
- createSlice 返回值是一个对象
- 对象包含所有的 actions 和 reducer;
store的创建
configureStore用于创建store对象,常见参数如下:
- reducer,将slice中的reducer可以组成一个对象传入此处;
- middleware:可以使用参数,传入其他的中间件(自行了解);
- devTools:是否配置devTools工具,默认为true;
store接入应用
在app.js中将store接入应用:
- Provider,内容提供者,给所有的子或孙子组件提供store对象;
- store: 使用useWrappedStore函数导出的store对象;
开始使用store
在函数式组件中可以使用 react-redux 提供的 Hooks API 连接、操作 store。
- useSelector 允许你使用 selector 函数从 store 中获取数据(root state)。
- useDispatch 返回 redux store 的 dispatch 引用。你可以使用它来 dispatch actions。
- useStore 返回一个 store 引用,和 Provider 组件引用完全一致。
Redux Toolkit异步Action操作
在之前的开发中,我们通过redux-thunk中间件让dispatch中可以进行异步操作。
Redux Toolkit默认已经给我们继承了Thunk相关的功能:createAsyncThunk
当createAsyncThunk创建出来的action被dispatch时,会存在三种状态:
- pending:action被发出,但是还没有最终的结果;
- fulfilled:获取到最终的结果(有返回值的结果);
- rejected:执行过程中有错误或者抛出了异常;
我们可以在createSlice的entraReducer中监听这些结果:见右图
项目介绍
网页云音乐-商城
项目需安装的依赖
样式
npm i normalize.css --save
npm i sass --save
npm i classnames --save
Redux And Toolkit
npm i next-redux-wrapper --save
npm i @reduxjs/toolkit react-redux --save
Axios( 最新的版本发现有bug )
npm i axios@1.1.3 --save
AntDesign
npm i antd –save
npm i -D @types/antd
安装 Ant Design 5
Ant Design 官网:https://ant.design/docs/react/use-in-typescript-cn
Next.js 应用安装Ant Design5
- 第一步:
- npm i antd
- npm i -D @types/antd
- 第二步:
- 统一样式风格
- 第三步:
- 就可以开始使用了
注意事项:
- antd 默认支持基于 ES modules 的 tree shaking
- 直接引入
import { Button } from 'antd'
就会有按需加载的效果
项目打包和部署
项目打包
- 执行
npm run build
(整个项目是部署产物) - 执行
npm run start
本地预览效果
使用Node部署
- 运行:
npm run start
- 指定端口:
PORT=9090 npm run start
使用PM2部署(推荐)
- 项目根目录运行:
pm2 start npm --name ”music-mall" -- run start
pm2 start npm
:在当前目录执行npm--name
:指定应用程序的名称--
:后面所有参数会传递给 npm 程序
- OR:
pm2 start “npm run start” –-name music-mall
PM2 常用命令
PM2 常用命令