• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

React--Redux④(RTK工具包)

武飞扬头像
一如彷徨
帮助1

RTK工具包

  • Redux Toolkit 是官方推荐用于编写 Redux 逻辑的工具包
  • 由于 Redux 的逻辑编写过于繁琐,并且代码通拆分在多个文件中,Redux Toolkit 旨在成为编写 Redux 逻辑的标准方式,从而解决代码繁琐的问题
  • 安装 Redux Toolkit
 npm i @reduxjs/toolkit

Redux Toolkit 的核心 API 主要如下:

  • configureStore: 包装 createStore 以提供简化的配置选项和良好的默认值,可以自动组合拆分的reducer,添加提供的任何 Redux 中间件(默认包含redux-thunk),并启用 Redux DevTools
  • createSlice: 接受 reducer 函数的对象、切片名称和初始状态值,自动生成切片 reducer,并带有相应的actions
  • createAsyncThunk: 接受一个 actionType 字符串和一个返回 Promise 的函数,生成一个基于该Promise 分派 actionTypethunk

基本使用

  • 原来的拆分模式是每个模块都有属于各自的 reduceractionCreators,使用 RTK 工具包对其重构
  • RTK 工具包官网: redux-toolkit.js.org/

通过 createSlice 创建切片,createSlice 主要包含以下参数和返回值

  • name: 标记切片的名词,会在 redux-devtool 中显示
  • initialState: 第一次初始化的值
  • reducers: 由函数组成的对象,相当于 reducer 函数,内部的函数类似每个 action 操作
  • 返回值: 一个对象,包含所有的 actionsreducer
 // store/counter.js
 import { createSlice } from '@reduxjs/toolkit';
 
 const counterSlice = createSlice({
   name: 'counter',
   
   initialState: {
     num: 888
   },
   
   reducers: {
     addNum(state, action) {
       state.num  = action.payload; // 这里做了优化,不需要返回新的state
     },
     subNum(state, action) {
       state.num -= action.payload;
     }
   }
 })
 
 export const { addNum, subNum } = counterSlice.actions
 export default counterSlice.reducer

使用 configureStore 创建 store 对象,常见参数如下:

  • reducer:slice 中的 reducer 组成一个对象传入
  • middleware: 可以使用参数,传入其他的中间件,默认集成 redux-thunkredux-devtool
  • devTools: 是否配置 devTools 工具,默认为 true
 import { configureStore } from '@reduxjs/toolkit';
 import counterReducer from './modules/counter';
 
 const store = configureStore({
   reducer: {
     counter: counterReducer
   },
   devTools: true
 })
 
 export default store
  • 组件中使用还是通过 react-reduxProvider 共享和 connect 映射

异步操作(createAsyncThunk)

  • Redux Toolkit 默认已经集成了 Thunk 相关的功能:createAsyncThunk
 import { createAsyncThunk } from '@reduxjs/toolkit';
 import axios from 'axios';
 
 export const fetchBannersAction = createAsyncThunk('fetch/banners', async () => {
   const { data: { data } } = await axios.get(url);
   return data
 })

使用 createAsyncThunk 创建出来的 actiondispatch 时,存在三种状态:

  • pending: action 被发出,但还没有最终的结果
  • fulfilled: 成功获取到最终的结果
  • rejected: 执行过程中出现错误或者抛出异常
 const homeSlice = createSlice({
   name: 'home',
   initialState: {
     banners: []
   },
   reducers: {},
   // 针对异步的action
   // extraReducers使用对象的写法在RTK2.0中准备弃用
   extraReducers: (builder) => {
     builder.addCase(fetchBannersAction.pending, (state, action) => {
       console.log(action.type); // fetch/banners/pending
     })
     .addCase(fetchBannersAction.fulfilled, (state, action) => {
       state.banners = action.payload.banner.list;
     })
     .addCase(fetchBannersAction.rejected, (state, action) => {
       console.log(action.type);
     })
   }
 })
  • 在不用 extraReducers 的情况下,使用普通的 reducers 也可改变 state 中的数据

createAsyncThunk 中的回调函数还有两个额外的参数:

  • extraInfo:额外信息,在调用 createAsyncThunk 返回的 Action 函数时传入的数据
  • store: 完整的 store
 export const fetchBannersAction = createAsyncThunk('fetch/banners', async (extraInfo, store) => {
   const { data: { data } } = await axios.get('http://123.207.32.32:8000/home/multidata');
   store.dispatch(changeBanners(data.banner.list)) // 这里可以直接分发action
 })
 
 const homeSlice = createSlice({
   name: 'home',
   initialState: {
     banners: []
   },
   reducers: {
     changeBanners(state, action) {
       state.banners = action.payload
     }
   },
 })
 
 export const { changeBanners } = homeSlice.actions;
 export default homeSlice.reducer;
  • 像上面的做法也可以分发 action(本人比较喜欢),但还是使用官方推荐的 extraReducers

数据不可变(Immutable)

  • React 开发中,无论是类组件中的 state,还是 redux 中管理的 state,甚至在整个 JavaScript 编码过程中,数据的不可变性都是非常重要的,所以 React 经常会进行浅拷贝来完成某些操作

浅拷贝事实上也是存在问题:

  • 对过大的对象进行浅拷贝会造成性能的浪费
  • 浅拷贝后的对象,在作深层改变时,依然会对之前的对象产生影响
 const friends = [
   { name: 'Jimmy' }
 ];
 
 const newFriend = [ ...friends ];
 newFriend[0].name = 'James' // 这里改变newFriend,friends里的对象也会被改变
  • 事实上 Redux Toolkit 底层使用了 immerjs 库来保证数据的不可变性
  • Immutable 对象的特点: 只要修改了对象,就会返回一个新对象,旧对象不会发生改变

为了节约内存使用新的算法:Persistent Data Structure(持久化数据结构)

  • 用一种数据结构来保存数据
  • 当数据被修改时会返回一个对象,但新对象会尽可能利用之前的数据结构,而不会对内存造成浪费

学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgbafia
系列文章
更多 icon
同类精品
更多 icon
继续加载