S12-06 小程序-Taro
[TOC]
入门
概述
认识 Taro 框架
什么是 Taro?
Taro 是由京东 凹凸实验室 打造的一个开放式跨端、跨框架解决方案,并于 2018 年 6 月 7 日正式开源。
Taro 支持使用 React/Vue/Preact等框架来开发 微信/ 京东/ 百度/ 支付宝/ 字节跳动/ QQ等小程序 / H5 / RN 等应用。
Taro 的版本史
Taro 1.x / 2.x 版的文档,现已不再积极维护。
2021 年 3 月,Taro 3.1版本正式发布,主要改动是打造开放式架构,支持以插件的形式编译到任意小程序平台。
2021 年 4 月,Taro 3.2 版本正式发布,新增了对 ReactNative 的支持,主要是由 58 同城团队主导。
2021 年 4 月,Taro 3.3 alpha 发布,主要改动是支持使用 HTML 标签进行开发。
2022 年 1 月,Taro 3.4版本正式发布,主要改动是支持使用 Preact 和 Vue3.2 进行开发。
目前 Taro 团队的迭代重心在于 Taro 3,Taro 1 / 2 只会对重大问题进行修复,不会新增新特性。
Taro 的特点
多端支持
Taro 3 可以支持转换到 H5、ReactNative 以及任意小程序平台(重心是小程序端)。
目前官方支持转换的平台如下:
H5、ReactNative、微信小程序、京东小程序、百度小程序、支付宝小程序、字节跳动小程序
QQ 小程序、钉钉小程序、企业微信小程序、支付宝小程序等
多框架支持
- 在 Taro 3 中可以使用完整的 React / Vue2 / Vue3 / Nervjs / Preact 开发体验
Taro vs uni-app
跨端支持度
社区活跃度
资料完善度
- Taro: 官方文档较完整,但不是很丰富,资料一般。
- uni-app:官方文档和各种专题内容很丰富,资料齐全。
工具和周边生态
Taro:官方的 Taro UI,只支持小程序和 H5( 不支持 RN ),截至到 2019 年 10 月 28 日, Taro 只有 64 个插件。
uni-app:官方的 uni-ui 支持多端、周边模板丰富、完善的插件市场,截至到 2019 年 10 月 28 日,有 850 个插件。
Taro 和 uni-app 如何选择?
如需要跨平台,并且应用不是很复杂,可选 Taro 和 uni-app。
如熟悉 Vue 可优先选择 uni-app; 如熟悉 React 推荐使用 Taro。
uni-app 在资料、生态、工具、开发效率、跨端数会比 Taro 略胜一筹。
当然 Taro 也有独特的优势,如:用 React 开发非常的灵活。
Taro 架构图设计图
Taro 当前的架构主要分为:编译时 和 运行时。
其中编译时主要是将 Taro 代码通过 Babel[11] 转换成 小程序的代码,如:JS、WXML、WXSS、JSON。
运行时主要是进行一些:生命周期、事件、data 等部分的处理和对接,以保证和宿主平台数据的一致性。
编辑器选择
推荐使用 VSCode或 WebStorm。
当你使用 VSCode 时,推荐安装 ESLint 插件 ,
如果你使用 TypeScript,别忘了配置 eslint.probe 参数。
如果使用 Vue,推荐安装 Vetur 或 Volar 插件,目前(2024-8-13)已被 Vue - Official代替。
如果你愿意花钱又懒得折腾可以选择 WebStorm,基本不需要配置。
不管使用 VSCode 还是 WebStrom,安装了上述插件之后使用 Taro 都实现自动补全和代码实时检查(linting)的功能。
初体验
安装
node 环境: Taro 项目基于 node,请确保已具备较新的 node 环境(>=16.20.0)
安装:
1、使用 npm 或者 yarn 全局安装 @tarojs/cli,或者直接使用 npx:
pnpm i @tarojs/cli -g # pnpm
npm i @tarojs/cli -g # npm
yarn global add @tarojs/cli # yarn
2、查看 Taro CLI 工具版本
npm info @tarojs/cli
3、查看@tarojs/cli 所有发行版本
pnpm view @tarojs/cli versions
项目初始化
1、方式一:使用命令创建模板项目
taro init myApp
2、方式二:npm 5.2+ 也可在不全局安装的情况下使用 npx 创建模板项目
npx @tarojs/cli init myApp
3、安装依赖
pnpm i
注意:
开发支付宝小程序时,Webpack4 暂不支持使用 React18。
受小程序环境限制,诸如新 SSR Suspense 等特性将不能在小程序中使用。
RN 暂不支持 React18,需要等待 RN 官方输出支持方案。
为了顺利地用 Taro 来开发 App,我们强烈地建议您,先对 React Native 开发进行学习。
编译运行
使用 Taro 的 build
命令可以把 Taro 代码编译成不同端的代码,然后在对应的开发工具中查看效果。
Taro 编译分为 dev
和 build
模式:
dev 模式(增加 --watch 参数) 将会监听文件修改。
sh# yarn - 启动 yarn dev:h5 yarn dev:weapp # pnpm - 启动 pnpm run dev:h5 pnpm run dev:weapp
注意: 启动小程序时需要手动打开项目目录的
/dist/
文件夹下的项目build 模式(去掉 --watch 参数) 将不会监听文件修改,并会对代码进行压缩打包。
sh# yarn - 打包 yarn build:h5 yarn build:weapp # pnpm - 打包 pnpm run build:h5 pnpm run build:weapp
dev 模式生成的文件较大,设置环境变量
NODE_ENV
为production
可以开启压缩,方便预览,但编译速度会下降。
目录结构
Taro+React 开发规范
为了实现多端兼容,综合考虑编译速度、运行性能等因素,Taro 可以约定了如下开发规范:
页面文件遵循 React 组件 JSX 规范。
组件标签 靠近小程序规范(但遵从大驼峰,并需导包),详见 Taro 组件规范
接口能力(JS API)靠近微信小程序规范,但需将前缀 wx 替换为 Taro(需导包),详见Taro 接口规范
数据绑定及事件处理同 React 规范,同时补充了 App 及页面的生命周期
为兼容多端运行,建议使用flex 布局进行开发,推荐使用 px 单位(750 设计稿)。
在 React 中使用 Taro 内置组件前,必须从 @tarojs/components 进行引入。
文档直接查看 Taro 的官网文档: https://docs.taro.zone/docs
配置文件
webpack 编译配置 config
编译配置存放于项目根目录下的 config 目录中,包含三个文件:
index.js
:是通用配置dev.js
:是项目开发时的配置prod.js
:是项目生产时的配置
常用配置项:
projectName : 项目名称
date : 项目创建时间
designWidth: 设计稿尺寸
sourceRoot : 项目源码目录
outputRoot: 项目产出目录
defineConstants: 定义全局的变量(DefinePlugin),需要如下写:
VERSION: "'1.0.O'"
alias: 配置路径别名
h5.webpackChain: webpack 配置
h5.devServer :开发者服务配置
全局配置 app.config.js
app.config.js 用来对小程序进行全局配置,配置项遵循微信小程序规范,类似微信小程序的 app.json,并对所有平台进行统一
更多的配置:https://docs.taro.zone/docs/next/app-config
页面配置 .config.js
每一个小程序页面都可以使用 .config.js 文件来对本页面的窗口表现进行配置。
页面中配置项在当前页面会覆盖全局配置 app.config.json 的 window 中相同的配置项。
文件需要 export 一个默认对象,配置项遵循微信小程序规范,并且对所有平台进行统一。
更多页面配置:https://docs.taro.zone/docs/next/page-config
项目配置 project.x.json
为了适配不同的小程序, Taro 支持各个小程序平台添加各自项目配置文件。
- 默认 project.config.json 配置只能用于微信小程序。
project.config.json 常用配置
libVersion 小程序基础库版本
projectname 小程序项目名字
appid 小程序项目的 appid
setting 小程序项目编译配置
各类小程序平台均有自己的项目配置文件,例如:
微信小程序,project.config.json
百度小程序,project.swan.json
字节跳动小程序,project.tt.json
支付宝小程序,project.alipay.json
等等
基础
内置组件
入口组件 app.js
每一个 Taro 应用都需要一个入口组件(如 React 组件)用来注册应用。入口文件默认是 /src/app.js
。
作用: 在入口 app.js 组件中我们可以:
定义应用的生命周期
- onLaunch():
useEffect
:在小程序环境中对应 app 的 onLaunch。 - componentDidShow():
useDidShow
:在小程序环境中对应 app 的 onShow 。 - componentDidHide():
useDidHide
:在小程序环境中对应 app 的 onHide 。
- onLaunch():
定义全局数据
- taroGlobalData
定义全局样式
定义应用的全局状态:
- Redux
- Vuex
- Pinia
一、定义应用的生命周期
二、定义全局数据
1、在 app.js 中定义全局数据
2、在页面中获取全局数据
三、定义全局样式
在app.scss
中定义全局样式
常用内置组件
View:视图容器。用于包裹各种元素内容(Taro3.3 以后支持使用 HTML 标签 进行开发)
Text:文本组件。用于包裹文本内容。
Button:按钮组件,多端主题色一样。
Image:图片。支持 JPG、PNG、SVG、WEBP、GIF 等格式以及云文件 ID。
- 默认宽高:
- H5:图片宽高
- weapp:Image 组件的默认宽高
- 支持import 导入 和 URL网络图片。不支持路径写法(包括绝对路径,相对路径)
- 默认宽高:
Scrollview:可滚动视图区域,用于区域滚动。
使用竖向滚动时,需要给
<scroll-view>
一个固定高度,通过 css 设置 height使用横向滚动时,需要给
<scroll-view>
添加 white-space: nowrap;样式,子元素设置为行内块级元素。小程序中,请勿在 scroll-view 中使用 map、video 等原生组件,也不要使用 canvas、textarea 原生组件。
Swiper:滑块视图容器,一般作为 banner 轮播图,默认宽 100%,高 150px。
View / Text
Button
Image
Scrollview
垂直滚动
水平滚动
Swiper
样式
设计稿及尺寸单位(px)
Taro 默认以 750px 作为换算尺寸标准,如设计稿不是 750px 为标准需修改 designWidth
比如:设计稿是 640px,则需修改 config/index.js 中 designWidth 为 640
在 Taro 中单位建议使用 px、 百分比 %,Taro 默认会对所有单位进行转换。
在 Taro 中写尺寸按照 1:1 关系来写,即设计稿量长度 100px,那么尺寸就写 100px,
当转成微信小程序时尺寸为 100rpx,当转成 H5 时尺寸以 rem 为单位。
如你希望部分 px 单位不被转换成 rpx 或 rem ,最简单做法就是在 px 单位中增加一个大写字母。
JS 中行内样式的转换
在编译时,Taro 会帮你对样式做尺寸转换操作
但是如果是在 JS 中书写了行内样式,那么编译时就无法做替换了
针对这种情况,Taro 提供了 API Taro.pxTransform() 来做运行时的尺寸转换。
示例:
CSS 编译时忽略
1、忽略单个属性: 当前忽略单个属性的最简单的方法,就是 px 单位使用大写字母。
2、忽略样式文件: 对于头部包含注释 /* postcss-pxtransform disable */
的文件,插件不予转换处理。
3、忽略行内样式: 行内样式默认不会被转换,如果想要转换需要使用 Taro.pxTransform()
全局和局部样式
全局样式
Taro 页面和普通组件导入的样式默认都是全局样式
那在 Taro 中应该如何编写局部的样式呢?使用 CSS Modules 功能
局部样式
1、在 config/index.js 配置文件中启用 CSS Modules 的功能,改完后重新运行pnpm run dev
2、编写的样式文件需要加上 .module 关键字。如: index*.module*.scss
3、然后在组件中导入该样式文件,即可以按照模块的方式使用了。
4、CSS Modules 中也支持编写全局样式
背景图片
Taro 支持使用在 css 里设置背景图片,使用方式与普通 web 项目大体相同,但需要注意以下几点:
- 支持 base64 格式图片,支持网络路径图片。
使用本地背景图片需注意:
小程序不支持在 css 中使用本地文件,包括本地的背景图和字体文件。需以 base64 方式方可使用。
为了方便开发,Taro 提供了直接在样式文件中引用本地资源的方式,其原理是通过 PostCSS 的 postcss-url插件将样式中本地资源引用转换成 Base64 格式,从而能正常加载。
在
/config/index.js
中的mini.url.config.maxSize: 2024
,单位:KB,设置转化 base64 的最大尺寸限制:不建议使用太大的背景图,大图需挪到服务器上,从网络地址引用。
本地背景图片的引用支持:相对路径和绝对路径 。
字体图标
注意: 和 uni-app 语法一样
Taro 支持使用字体图标,使用方式与普通 web 项目相同:
第一步:先生成字体图标文件
第二步:app.scss 引入字体图标
第三步:组件中使用自定义字体
页面和传参
Page
创建页面方式:
1、命令行创建: 能够在当前项目的 pages 目录下快速生成新的页面文件,并填充基础代码,是一个提高开发效率的利器。
# --name可以省略
Taro create --name [页面名称]
2、手动创建页面: 在目录根目录下的 pages 目录下新建即可。
注意: 新建的页面,都需在 app.config.json
中的 pages 列表上配置。
删除页面: 删除页面,需做两件工作
删除页面对应的文件
删除 app.config.json 中对应的配置
Tabbar
在 app.config.js 中配置 Tabbar
icon 路径支持绝对路径和相对路径
页面路由
Taro 有两种页面路由跳转方式:使用 Navigator组件跳转、调用API跳转。
组件:Navigator
常用 API:navigate 、redirectTo、switchTab、navigateBack
页面通讯
在 Taro 中,常见页面通讯方式:
方式一:url 查询字符串
方式二:EventChannel(只支持小程序端)
方式三:全局事件总线: Taro.eventCenter
方式四:全局数据:taroGloabalData
方式五:本地数据存储: Taro.setStorageSync(key, data) 等
方式六:Redux 状态管理库
查询字符串-正向
传递参数:?name=liujun&id=100
获取参数:
onLoad 、 useLoad 生命周期获取路由参数
Taro.getCurrentInstance().router.params 获取路由参数。
1、传参:直接在 url 后面通过查询字符串的方式拼接
2、接收:
方式一:在
onLoad
或useLoad
生命周期中通过options.xxx
获取 url 传递的参数方式二:通过
Taro.getCurrentInstance().router.params
获取 url 传递的参数方式三:通过 hooks 获取参数
EventChannel-正向
注意: 只支持小程序端
1、传参:在success
回调中通过res.eventChannel.emmit(事件, 参数)
传递参数
2、接收:在onLoad
生命周期中通过this.$instance.page.getOpenerEventChannel()
获取参数
注意: 在 uni-app 中是通过this.getOpenerEventChannel()
获取eventChannel
对象的。
EventChannel-逆向
1、跳转到目标页
2、在目标页点击返回按钮,跳转回来源页,并通过 eventChannel 携带参数
注意: 获取当前 page 的 eventChannel 的方法:
- js
// 方法一 $instace = Taro.getCurrentInstance() const eventChannel = this.$instance.page.getOpenerEventChannel()
- js
// 方法二 const pages = Taro.getCurrentPages() const page = pages[pages.length - 1] const eventChannel = page.getOpenerEventChannel()
3、在来源页,通过 navigateTo 的 envets 选项中监听发射过来的事件,并获取传递的参数
事件总线-逆向
为了支持跨组件、跨页面之间的通信,Taro 提供了全局事件总线:Taro.eventCenter
- Taro.eventCenter.trigger():
(eventName, args)
,触发一个事件- eventName:
string
,默认:
,事件名称 - args:
any
,默认:
,事件参数
- eventName:
- Taro.eventCenter.on():
(eventName, cb)
,监听一个事件- eventName:
string
,默认:
,事件名称 - cb:
(args => void)
,默认:
,事件监听函数- args :
any
,默认:
,触发事件参数
- args :
- eventName:
- Taro.eventCenter.off():
(eventName, cb?)
,取消监听事件。如果没有提供参数,则移除所有的事件监听器- eventName:
string
,默认:
,事件名称 - cb?:
(args => void)
,默认:
,事件监听函数- args :
any
,默认:
,触发事件参数
- args :
- eventName:
注意:
需先监听,再触发事件,比如:你在 A 界面触发,然后跳转到 B 页面后才监听是不行的。
通常 on 和 off 是同时使用,可以避免多次重复监听
适合页面返回传递参数、适合跨组件通讯,不适合界面跳转传递参数。即适合逆向传参,不适合正向传参
1、跳转到目标页
2、在目标页触发事件,并传递参数
3、在来源页监听事件,并获取传递的参数
生命周期
Page 生命周期
Taro 页面组件除了支持 React 组件生命周期 方法外,还根据小程序的标准,额外支持以下页面生命周期:
- onLoad():
(options)
,小程序:onLoad()
,监听页面加载,该钩子被调用时,响应式数据、计算属性、方法、侦听器、props、slots 已设置完成。- options:
object
,上个页面传递的数据。 - 注意: 通过访问 options 参数或调用 getCurrentInstance().router,可以访问到页面路由参数。
- options:
- onUnload ():
()
,小程序:onUnload()
,监听页面卸载。- 注意: 建议使用 React 的 componentWillUnmount 生命周期处理页面卸载时的逻辑。
- onReady():
()
,小程序:onReady()
,监听页面初次渲染完成,此时组件已挂载完成,DOM 树($el)已可用,注意如果渲染速度快,会在页面进入动画完成前触发。- 注意: 可以使用 createCanvasContext 或 createSelectorQuery 等 API 访问小程序渲染层 DOM 节点
- componentDidShow():
()
,小程序:onShow()
,监听页面显示,页面每次出现在屏幕上都触发,包括从下级页面点返回露出当前页面。 - componentDidHide ():
()
,小程序:onHide()
,监听页面隐藏。 - onPullDownRefresh():,监听用户下拉动作,一般用于下拉刷新。
- 启用下拉刷新: 设置
index.config.js
中的definePageConfig.enablePulldownRefresh: true
- 关闭下拉刷新:
Taro.stopPullDownRefresh()
- 启用下拉刷新: 设置
- onReachBottom():``,页面滚动到底部的事件(不是 scroll-view 滚到底),常用于下拉下一页数据。
更多:https://docs.taro.zone/docs/react-page/#生命周期方法
Hooks 生命周期
Taro 使用 Hooks 很简单。Taro 专有 Hooks,例如 usePageScroll, useReachBottom,需从 @tarojs/taro 中引入
React 框架自己的 Hooks ,例如 useEffect, useState,从对应的框架引入。
更多的 Hooks 可查看官网: https://docs.taro.zone/docs/hooks
常用 API
网络请求
Taro.request(OBJECT) 发起网络请求
在各个小程序平台运行时,网络相关的 API 在使用前需要配置合法域名(域名白名单)。
微信小程序开发工具在开发阶段可以配置:不校验合法域名。
header 中的 content-type 属性的默认值为:application/json
封装请求
参考:uni-app 的封装
数据缓存
同步存取数据的方法:
Taro.setStorageSync():
(key, data)
,将数据存储在本地缓存中指定的 key 中。会覆盖掉原来该 key 对应的内容- 参数:key, data
- key:
string
,本地缓存中指定的 key - data:
any
,需要存储的内容。只支持原生类型、Date、及能够通过JSON.stringify
序列化的对象
Taro.getStorageSync():
(key)
,从本地缓存中同步获取指定 key 的内容- 参数:key
- key:
string
,本地缓存中指定的 key - 返回值:any
- any:
any
,key 对应的内容
Taro.removeStorageSync():
(key)
,从本地缓存中移除指定 key。- 参数:key
- key:
string
,本地缓存中指定的 key
Taro.clearStorageSync():
()
,清理本地数据缓存。异步存储数据的方法:
Taro.setStorage():
(object)
,将数据存储在本地缓存中指定的 key 中。会覆盖掉原来该 key 对应的内容- 参数:object
- key:
string
,本地缓存中指定的 key - data:
any
,需要存储的内容。只支持原生类型、Date、及能够通过JSON.stringify
序列化的对象 - success:
function(res)
,接口调用成功的回调函数 - fail:
function(err)
,接口调用失败的回调函数 - complete:
function(res)
,接口调用结束的回调函数(调用成功、失败都会执行)
Taro.getStorage():
(object)
,从本地缓存中异步获取指定 key 的内容- 参数:object
- key:
string
,本地缓存中指定的 key - success:
function(res)
,接口调用成功的回调函数 - fail:
function(err)
,接口调用失败的回调函数 - complete:
function(res)
,接口调用结束的回调函数(调用成功、失败都会执行)
Taro.removeStorage():
(object)
,从本地缓存中移除指定 key。- 参数:object
- key:
string
,本地缓存中指定的 key - success:
function(res)
,接口调用成功的回调函数 - fail:
function(err)
,接口调用失败的回调函数 - complete:
function(res)
,接口调用结束的回调函数(调用成功、失败都会执行)
Taro.clearStorage():
(object)
,清理本地数据缓存。- 参数:object
- success:
function(res)
,接口调用成功的回调函数 - fail:
function(err)
,接口调用失败的回调函数 - complete:
function(res)
,接口调用结束的回调函数(调用成功、失败都会执行)
进阶
自定义组件
组件及生命周期
在 Taro 中,除了应用和页面组件有生命周期之外, Taro 的组件也是生命周期,如下图所示:
下面我们来编写一个 HYButton 组件。
1、创建组件
使用组件
2、定义属性
3、样式编写
依赖包:
- classnames
- proptypes
启用设置:开启缓存、启用mini和h5的cssModules
在
xxx.modules.scss
中编写样式导入scss样式
4、定义插槽
使用
5、定义事件
组件内部定义一个click事件,并向外发射一个
onBtnClick
的事件组件外监听传递出来的事件
onBtnClick
6、定义组件生命周期和页面生命周期
组件生命周期:useEffect
页面生命周期:useLoad、useDidShow、useReady
注意: 在组件中编写页面生命周期的支持情况:
class 组件默认不行,需要单独处理
但是函数组件是支持的
跨端兼容实现
跨端兼容方案
Taro 的设计初衷就是为了统一跨平台的开发方式,并且已经尽力通过运行时框架、组件、API 去抹平多端差异,但是由于不同的平台之间还是存在一些无法消除的差异,所以为了更好的实现跨平台开发,Taro 中提供了如下的解决方案。
方案一:内置环境变量
Taro 在编译时提供了一些内置的环境变量来帮助用户做一些特殊处理。
通过这个变量来区分不同环境,从而使用不同的逻辑。在编译阶段,会移除不属于当前端的代码,只保留当前端的代码。
内置环境变量虽然可以解决大部分跨端的问题,但是会让代码中存在很多逻辑判断的代码,影了响代码的可维护性,而且也让代码变得丑陋。
为了解决这种问题,Taro 提供了另外一种跨端开发的方式作为补充。
方案二:统一接口的多端文件
开发者可以通过将文件修改成 原文件名 + 端类型 的命名形式(端类型对应着 process.env.TARO_ENV 的取值),不同端的文件代码对外保持统一接口,而引用的时候仍然是 import 原文件名的文件。
Taro 在编译时,会跟根据当前编译平台类型,精准加载对应端类型的文件,从而达到不同的端加载其对应端的文件。
内置环境变量
内置环境变量( process.env.TARO_ENV),该环境变量可直接使用
process.env.TARO_ENV: 用于判断当前的编译平台类型,有效值为:weapp / swan / alipay / tt / qq / jd / h5 / rn。
通过这个变量来区分不同环境,从而使用不同的逻辑。
在编译阶段,会移除不属于当前平台的代码,只保留当前平台的代码,例如:
注意: 不要解构 process.env 来获取环境变量,请直接以完整书写的方式(process.env.TARO_ENV)来进行使用。
统一接口的多端文件
统一接口的多端文件这一跨平台兼容写法有如下三个使用要点:
1、不同端的对应文件一定要统一接口和调用方式。
2、引用文件的时候,只需写默认文件名,不用带文件后缀。
3、最好有一个平台无关的默认文件,这样在使用 TS 的时候也不会出现报错。
常见有以下使用场景:
多端组件(属性,方法,事件等需统一)
- 针对不同的端写不同的组件代码
多端脚本逻辑(属性、方法等需统一)
- 针对不同的端写不同的脚本逻辑代码
多端脚本
index.js
index.h5.js
index.weapp.js
使用
Redux
认识RTK
依赖包:
- react-redux
- @reduxjs/toolkit
安装:
pnpm i @reduxjs/toolkit react-redux
Redux Toolkit 是官方推荐的编写 Redux 逻辑的方法。
以前我们在使用 redux 的时候,通常会将 redux 代码拆分在多个文件中,比如:constants、action、reducer 等
这种代码组织方式过于繁琐和麻烦,导致代码量过多,也不利于后期管理
Redux Toolkit 就是为了解决这种编码方式而诞生。
并且以前的 createStore 方式已标为过时,而 Redux Toolkit 已成为官方推荐;
API
Redux Toolkit的核心API主要是如下几个:
- configureStore({ reducer, middleware, devTools, ... }):
返回:store
,包装createStore以提供简化的配置选项和良好的默认值。它可以自动组合你的 slice reducer,添加你提供的任何 Redux 中间件,redux-thunk默认包含,并启用 Redux DevTools Extension。- 参数
- reducer:``,Redux store 的根 reducer
- middleware:``,要使用的中间件数组
- devTools:``,是否启用开发工具(如 Redux DevTools),默认true
- preloadedState:``,初始状态
- enhancers:``,其他 store 增强器
- 返回
- store:``,返回的是一个 Redux store 实例,而不是一个类。因此无法创建多个 store 实例
- createSlice({ name, initialState, reducers,... }):
返回:reducerSlice
,用于创建一个Redux reducer和action creator的集合- 参数
- name:
String
,用于标识这个reducer的名称,action.type
会根据name生成 - initialState:
any
,表示这个reducer的初始状态 - reducers:
{ reducer,... }
,用于定义这个reducer的action creator和对应的reducer函数- reducer:
(state, action) => void
,相当于之前的reducer函数
- reducer:
- extraReducers:
{ reducer,... }
,包含了与当前slice无关的reducer函数- reducer:
(state, action) => void
,相当于之前的reducer函数
- reducer:
- 返回
- reducerSlice:``,返回一个reducer片段
- createAsyncThunk(typePrefix, payloadCreator, options? ):
返回:
,用于创建一个异步action creator- 参数
- typePrefix:
String
,用于标识这个异步action creator的类型前缀 - payloadCreator:
(arg, thunkAPI) => Promise
,用于处理异步操作并返回一个Promise对象 - options?:
Object
,用于配置异步action creator的一些选项- fulfilled:用于指定异步操作成功时的处理函数。
- rejected:用于指定异步操作失败时的处理函数。
- pending:用于指定异步操作进行中时的处理函数。
- dispatchCondition:用于指定在什么条件下才会dispatch这个action的函数。
- condition:用于指定在什么条件下才会调用
payloadCreator
函数的函数。 - typeSuffixes:用于指定异步action creator的类型后缀的对象。
- serializeError:用于指定如何序列化异步操作的错误信息的函数。
创建 counter 模块的 reducer
我们先创建 counter 模块的 reducer: 通过 createSlice 创建一个 slice。
createSlice({ name, initialState, reducers,... }):返回:reducerSlice
,用于创建一个Redux reducer和action creator的集合
- 参数
- name:
String
,用于标识这个reducer的名称,action.type
会根据name生成 - initialState:
any
,表示这个reducer的初始状态 - reducers:
{ reducer,... }
,用于定义这个reducer的action creator和对应的reducer函数- reducer:
(state, action) => void
,相当于之前的reducer函数
- reducer:
- extraReducers:
{ reducer,... }
,包含了与当前slice无关的reducer函数- reducer:
(state, action) => void
,相当于之前的reducer函数
- reducer:
- 返回
- reducerSlice:``,返回一个reducer片段
store 的创建
configureStore({ reducer, middleware, devTools, ... }):返回:store
,包装createStore以提供简化的配置选项和良好的默认值。它可以自动组合你的 slice reducer,添加你提供的任何 Redux 中间件,redux-thunk默认包含,并启用 Redux DevTools Extension。
- 参数
- reducer:``,Redux store 的根 reducer
- middleware:``,要使用的中间件数组
- devTools:``,是否启用开发工具(如 Redux DevTools),默认true
- preloadedState:``,初始状态
- enhancers:``,其他 store 增强器
- 返回
- store:``,返回的是一个 Redux store 实例,而不是一个类。因此无法创建多个 store 实例
store 接入应用
在 app.js 中将 store 接入应用:
Provider,内容提供者,给所有的子或孙子组件提供 store 对象;
store: 使用 configureStore 创建的 store 对象;
开始使用 store
在函数式组件中可以使用 react-redux 提供的 Hooks API 连接、操作 store。
1、useSelector 允许你使用 selector 函数从 store 中获取数据(root state)。
2、useDispatch 返回 redux store 的 dispatch 引用。你可以使用它来 dispatch actions。
3、useStore 返回一个 store 引用,和 Provider 组件引用完全一致。
Redux Toolkit 异步 Action 操作
在之前的开发中,我们通过 redux-thunk 中间件让 dispatch 中可以进行异步操作。
Redux Toolkit 默认已经给我们继承了 Thunk 相关的功能:createAsyncThunk
createAsyncThunk(typePrefix, payloadCreator, options? ):返回:
,用于创建一个异步action creator
- 参数
- typePrefix:
String
,用于标识这个异步action creator的类型前缀 - payloadCreator:
(arg, thunkAPI) => Promise
,用于处理异步操作并返回一个Promise对象 - options?:
Object
,用于配置异步action creator的一些选项- fulfilled:用于指定异步操作成功时的处理函数。
- rejected:用于指定异步操作失败时的处理函数。
- pending:用于指定异步操作进行中时的处理函数。
- dispatchCondition:用于指定在什么条件下才会dispatch这个action的函数。
- condition:用于指定在什么条件下才会调用
payloadCreator
函数的函数。 - typeSuffixes:用于指定异步action creator的类型后缀的对象。
- serializeError:用于指定如何序列化异步操作的错误信息的函数。
当 createAsyncThunk 创建出来的 action 被 dispatch 时,会存在三种状态:
pending:action 被发出,但是还没有最终的结果;
fulfilled:获取到最终的结果(有返回值的结果);
rejected:执行过程中有错误或者抛出了异常;
我们可以在 createSlice 的 entraReducer 中监听这些结果:见下图
builder写法:
在组件中触发异步action