react+redux异步操作数据

react+redux异步操作数据

redux中操作异步方法,主要是: 1、借助createAsyncThunk()封装异步方法;2、通过extraReducers处理异步方法触发后的具体逻辑,操作派生的state

1、异步操作的slice

import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'// 使用该类型定义初始 state
const initialState = {systemName: '三分之一'
}
// promise封装的定时器
function delay(ms: number, data: string) {return new Promise((resolve) => setTimeout(() => resolve(data), ms))
}
// AsyncThunk<void, void, AsyncThunkConfig>
// createAsyncThunk<string, string, object> :
// 第一个string: 'system/updateSystemName'
// 第二个string: updateSystemName调用时,传的参数
// object: AsyncThunkConfig 配置对象
// 详细可见 : https://redux-toolkit.js.org/usage/usage-with-typescript#createasyncthunk
export const updateSystemName = createAsyncThunk<string, string>('system/updateSystemName',async (data, config): Promise<string> => {console.log(data, config)const res = await delay(2000, data)return res as string}
)const systemSlice = createSlice({name: 'system',initialState,reducers: {},extraReducers: (builder) => {// 触发updateSystemName,执行builder.addCase的回调builder.addCase(updateSystemName.fulfilled, (state, action) => {// action: {//   type: 'system/updateSystemName/fulfilled'// },// payload: dispatch(updateSystemName('单点的')) updateSystemName// meat: {arg: '单点的', ...}state.systemName = action.payload})}
})
export default systemSlice.reducer

AsyncThunkConfig 如图所示:
在这里插入图片描述

2、组件中调用异步的方法

import { updateSystemName } from '@/store/reducers/systemSlice'
import { RootState } from '@/store'
import { useAppDispatch } from '@/hooks/useAppDispatch'
import { useAppSelector } from '@/hooks/useAppSelector'const Home = () => {const { systemName } = useAppSelector((state: RootState) => state.systemReducer)const dispatch = useAppDispatch()const test = () => {// useDispatch() 返回值函数默认期望的参数类型是 AnyAction// 异步处理是updateSystemName: AsyncThunkAction// 所以这块使用官网推荐的自定义封装的hooks: useAppDispatchdispatch(updateSystemName('单点的'))}return (<><div>home page</div><p>{systemName}</p><button onClick={test}>测试</button></>)
}export default Home

4、给dispatch()参数添加Action类型

解决: 类型“AsyncThunkAction<string, string, AsyncThunkConfig>”的参数不能赋给类型“AnyAction”的参数。

  1. useAppDispatch
import type { AppDispatch } from '@/store'
import { useDispatch } from 'react-redux'// 给useDispatch 添加泛型, 默认接收的参数是AnyAction
// import {  useDispatch } from 'react-redux'
export const useAppDispatch = () => useDispatch<AppDispatch>()
  1. useAppSelector
import type { RootState } from '@/store'
import { TypedUseSelectorHook, useSelector } from 'react-redux'// import { useSelector } from 'react-redux'
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector
  1. store中
    export type RootState = ReturnType<typeof store.getState>
    export type AppDispatch = typeof store.dispatch
import { configureStore } from '@reduxjs/toolkit'
import { combineReducers } from 'redux'
// 数据持久化
import { persistStore, persistReducer } from 'redux-persist'
import storageLocation from 'redux-persist/lib/storage' // defaults to localStorage for web    // redux-persist/lib/storage/session
// reducers
import userReducer from './reducers/userSlice'
import systemReducer from './reducers/systemSlice'
const persistConfig = {key: 'root',storage: storageLocation
}
// 持久化reducers
const persistedReducer = persistReducer(persistConfig,combineReducers({//数据切片userReducer,systemReducer})
)const store = configureStore({// userReducer 模块名reducer: persistedReducer,middleware: (getDefaultMiddleware) =>getDefaultMiddleware({serializableCheck: false})
})// 可以订阅 store
// store.subscribe(() => console.log(store.getState(), 'userSlice'))// 持久化的store
const persistor = persistStore(store)export { store, persistor }// Infer the `RootState` and `AppDispatch` types from the store itself
export type RootState = ReturnType<typeof store.getState>
// Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState}
export type AppDispatch = typeof store.dispatch

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/5659.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

uniapp 之 微信小程序、支付宝小程序 对于自定义导航栏的不同

目录 前言 微信小程序 代码 支付宝小程序 首页配置文件 二级菜单页面 配置 总结 不同 相同 前言 小程序都是 uni-app 写的 不是原生 微信小程序 代码 pages.json文件中配置 重点&#xff1a; "navigationStyle": "custom", // 导航栏样式…

【N32L40X】学习笔记05-串口库(空闲中断+接收非空中断)

串口 该函数库的目的就是在统一的地方配置&#xff0c;将配置的不同项放置在一个结构体内部使用一个枚举来定义一个的别名 bsp_uart.h #ifndef _BSP_UART_H_ #define _BSP_UART_H_ #include<stdio.h> #include<stdint.h> #include "n32l40x.h"#define…

ChatGPT开放自定义系统级别的指令,可设置偏好变成专属助理

OpenAI官方消息https://openai.com/blog/custom-instructions-for-chatgpt OpenAI为其大型语言模型接口ChatGPT引入了自定义指令&#xff0c;旨在为用户提供更加量身定制和个性化的体验&#xff0c;可以设置您的偏好&#xff0c;ChatGPT将在未来的所有对话中记住它们。 该功…

Redis高可用部署架构

目录 1. 主从复制与哨兵架构&#xff1a;2. Redis集群架构&#xff1a; Redis高可用部署可以采用主从复制与哨兵架构或Redis集群架构。下面将分别介绍这两种架构的架构图、优缺点和具体应用场景。 1. 主从复制与哨兵架构&#xff1a; 架构图&#xff1a; ----------| Client…

Python—数据结构(一)

先放一张自己学习和整理归纳的思维导图&#xff0c;以便让大家都知道我自己的整体学习路线。 数据结构的学习路上内容枯燥&#xff0c;但坚持下来一定有很大的收获&#xff01;加油&#x1f4aa;&#x1f3fb;&#xff01; 数据结构 数据的概念数据元素&#xff1a; 若干基本…

Go语言通过反射获取各种类型变量的值

Go语言通过反射获取各种类型变量的值 反射是程序在运行期间获取变量的类型和值、或者执行变量的方法的能力。 1、什么是反射 反射是程序在运行期间获取变量的类型和值、或者执行变量的方法的能力。 Golang 反射包中有两对非常重要的函数和类型&#xff0c;两个函数分别是&a…

音视频开发-ffmpeg介绍-系列二

目录 一、FFmpeg核心结构体 二、解码流程 三、FFmpeg解码实现 四、FFmpeg编码实现 五、FFmpeg转码实现 一、FFmpeg核心结构体 AVFormatContext&#xff1a;解封装功能的结构体&#xff0c;包含文件名、音视频流、时长、比特率等信息&#xff1b; AVCodecContext&#xf…

【算法基础:数学知识】4.3 欧拉函数

文章目录 欧拉函数定义性质 例题列表873. 欧拉函数&#xff08;使用质因数分解求一个数的欧拉函数&#xff09;原理讲解&#xff08;公式推导&#xff09;⭐解法代码 874. 筛法求欧拉函数&#xff08;求 1 ~ n 中所有数字的欧拉函数&#xff09;⭐ 欧拉函数 https://oi-wiki.o…

[数据结构 -- 手撕排序算法第六篇] 递归实现快速排序(集霍尔版本,挖坑法,前后指针法为一篇的实现方法,很能打)

目录 1、常见的排序算法 1.1 交换排序基本思想 2、快速排序的实现方法 2.1 基本思想 3 hoare&#xff08;霍尔&#xff09;版本 3.1 实现思路 3.2 思路图解 3.3 为什么实现思路的步骤2、3不能交换 3.4 hoare版本代码实现 3.5 hoare版本代码测试 4、挖坑法 4.1 实现…

Java设计模式解析:迭代器模式的实现与应用

迭代器模式是一种行为型设计模式&#xff0c;它提供了一种统一的方式来遍历集合中的元素&#xff0c;而无需暴露集合的内部结构。在本文中&#xff0c;我们将深入探讨迭代器模式的实现和应用。 在软件开发中&#xff0c;集合是一种常见的数据结构&#xff0c;用于存储和管理一…

【手撕排序算法】---基数排序

个人主页&#xff1a;平行线也会相交 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 平行线也会相交 原创 收录于专栏【数据结构初阶&#xff08;C实现&#xff09;】 我们直到一般的排序都是通过关键字的比较和移动这两种操作来进行排序的。 而今天介绍的…

​MySQL高阶语句(三)

目录 1、内连接 2、左连接 3、右连接&#xff1a; 二、存储过程⭐⭐⭐ 4. 调用存储过程 5.查看存储过程 5.1 查看存储过程 5.2查看指定存储过程信息 三. 存储过程的参数 3.1存储过程的参数 3.2修改存储过程 四.删除存储过程 MySQL 的连接查询&#xff0c;通常都是将来…

微服务一 实用篇 - 5.分布式搜索引擎(ElasticSearch基础)

《微服务一 实用篇 - 5.分布式搜索引擎&#xff08;ElasticSearch基础&#xff09;》 提示: 本材料只做个人学习参考,不作为系统的学习流程,请注意识别!!! 《微服务一 实用篇 - 5.分布式搜索引擎&#xff08;ElasticSearch基础&#xff09;》 《微服务一 实用篇 - 5.分布式搜索…

【广州华锐互动】列车人员疏散VR虚拟演练系统

随着科技的不断发展&#xff0c;虚拟现实(VR)技术已经逐渐应用于各个领域。在火车站安全方面&#xff0c;为了提高旅客的安全意识和应对突发事件的能力&#xff0c;列车人员疏散VR虚拟演练系统应运而生。 列车人员疏散VR虚拟演练系统是一种基于虚拟现实技术的教育培训系统&…

数据结构问答7

1. 图的定义和相关术语 答: 定义:图是由顶点集V和边集E组成,其中V为有限非空集。 相关术语:n个顶点,e条边,G=(V,E) ① 邻接点和端点:无向图中,若存在一条边(i, j),则称i,j为该边的端点,且它们互为邻接点;在有向图中,若存在一条边<i, j>,则称i,j分别为…

js浅拷贝与深拷贝

var value 10; var valueCopy value; valueCopy 1000 console.log(value, valueCopy) // 10 1000以上value结果的值没有随着valueCopy的改变而改变是因为数字&#xff0c;字符串是原始值&#xff0c;当重新给它赋值时不会在原地址修改而是新开一块地址 引用类型就是指向同…

【Vue】day03-VueCli(脚手架)

day03 一、今日目标 1.生命周期 生命周期介绍 生命周期的四个阶段 生命周期钩子 声明周期案例 2.综合案例-小黑记账清单 列表渲染 添加/删除 饼图渲染 3.工程化开发入门 工程化开发和脚手架 项目运行流程 组件化 组件注册 4.综合案例-小兔仙首页 拆分模块-局部…

SpringBoot 如何使用 MockMvc 进行 Web 集成测试

SpringBoot 如何使用 MockMvc 进行 Web 集成测试 介绍 SpringBoot 是一个流行的 Java Web 开发框架&#xff0c;它提供了一些强大的工具和库&#xff0c;使得开发 Web 应用程序变得更加容易。其中之一是 MockMvc&#xff0c;它提供了一种测试 SpringBoot Web 应用程序的方式&…

什么是神经网络?

我们常常使用深度学习来指训练神经网络的过程。 在这里举一个房屋价格预测的例子&#xff1a;假设有一个数据集&#xff0c;它包含了六栋房子的信息。所以&#xff0c;你知道房屋的面积是多少平方米&#xff0c;并且知道这个房屋的价格。这是&#xff0c;你想要拟合一个根据房屋…

el-form 初值和resetFields问题

配置片段。 给dataForm动态赋初值&#xff0c;必须如下&#xff0c;用 this.dataForm{}这种方式&#xff0c;其他的形式如 this.dataForm.属性、this.dataForm[属性] 都会失败且造成 el-form和resetFields 出现问题 <el-formref"dataForm":model"dataForm&qu…