Redux Toolkit+TypeScript最佳实践

Redux-Toolkit是为了简化使用Redux繁琐的步骤,可以j降低使用useReducer与useContext管理状态的频率,而且起到项目中状态管理规范和约束化的效果。

阅读本文需要的前置知识:React、Redux、Typescript、Redux hooks。

Redux-Toolkit使用步骤

目前使用Redux-Toolkit管理消费redux状态的方式。举个例子,假设我们现在的业务和银行转账有关,有两个状态存在redux,分别为银行账号和金额:accountOfBank和amountOfBank,使用createSlice来创建reducer和actions:

首先安装redux-toolkit依赖包,

npm i @reduxjs/toolkit

npm i react-redux

文件目录

slice.ts

创建切片,声明存储状态对象以及action。createSlice创建一个切片(slice),主要参数:

  • name:slice的标识,在redux-devtool中会显示对应的名字;
  • initialState:初始值,对象;
  • reducers:对象类型以及函数类型(函数参数:state和传递的action参数);
  • extraReducers:用于处理异步,比如网络请求等;

creactSlice返回值是一个对象,包含所有的actions。 

import { createSlice, PayloadAction } from '@reduxjs/toolkit';

type InitialState = {
    accountOfBank: string,
    amountOfBank: string
}


const initialState: InitialState = {
    accountOfBank: 'JanPan Bank',
    amountOfBank: '1000'
}

const slice = createSlice({
    name: 'bank',
    initialState,
    reducers: {
        updateBankAccount: (state: InitialState, action: PayloadAction<string>) => {
            state.accountOfBank = action.payload;
        },
        updateBankAmount: (state: InitialState, action: PayloadAction<string>) => {
            state.amountOfBank = action.payload;
        }
    }
})

export const {updateBankAccount, updateBankAmount} = slice.actions;
export default slice.reducer;

 store.ts

存在在store中,configureStore是Redux-Tookit的一个工厂函数,用于创建Redux-Store。

store是通过传入一个reducer(缩减器)来创建的,并通过getState的方法,用于返回当前的状态值,在Typescript强类型声明中有很大的帮助。

configureStore主要参数,

  • reducer:将slice的reducer传入;
  • middleware:中间件;
  • devTools:是否配置devTools工具,默认为true;
import { configureStore } from "@reduxjs/toolkit";
import slice from './slice';

export const store = configureStore({
    reducer: {
        bank: slice
    }
})

export type BankState = ReturnType<typeof store.getState>;

index.tsx

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import { Provider } from "react-redux";
import { store } from "./toolkit/store";
const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement
);
root.render(
    <Provider store={store}>
        <App />
    </Provider>
);

BankView.tsx

页面UI组件渲染,useSelector获取当前管理的state,state的类型可通过store.ts的getState获取,

并且将配置在store的reducer提取解构。

import { useDispatch, useSelector } from "react-redux";
import { BankState } from "../../toolkit/store";
import { updateBankAccount, updateBankAmount } from "../../toolkit/slice";

export const BankView = () => {
    const {accountOfBank, amountOfBank} = useSelector((state: BankState) => state.bank)

    const dispatch = useDispatch();

    return (
        <div>
            <h3>accountOfBank - {accountOfBank}</h3>
            <h3>amountBank - {amountOfBank}</h3>
            <button onClick={() => dispatch(updateBankAccount('England'))}>
                change bank account
            </button>
            <span>  </span>
            <button onClick={() => dispatch(updateBankAmount('2000'))}>
                change bank amount
            </button>
        </div>
    )
}

详细目录截图如下,

经过上面简单的封装就实现了全局状态管理,使用简单高效,而且可以实现业务与UI的解耦。

在网络请求等情况通常需要异常更新、提交数据等,可通过createAynceThunk实现,

import { createAsyncThunk, createSlice, PayloadAction } from '@reduxjs/toolkit';

type InitialState = {
    accountOfBank: string,
    amountOfBank: string,
    creatTime: string
}


const initialState: InitialState = {
    accountOfBank: 'JanPan Bank',
    amountOfBank: '1000',
    creatTime: '2024-04-02'
}


export const fetchAccountBank = createAsyncThunk(
    'https://wwww.baidu.com',
    () => {
        return new Promise<string>(resolve => {
            let timeId = setTimeout(() => {
                clearTimeout(timeId);
                resolve('2024-04-03');
            }, 1000)
        })
    })

const slice = createSlice({
    name: 'bank',
    initialState,
    reducers: {
        updateBankAccount: (state: InitialState, action: PayloadAction<string>) => {
            state.accountOfBank = action.payload;
        },
        updateBankAmount: (state: InitialState, action: PayloadAction<string>) => {
            state.amountOfBank = action.payload;
        }
    },
    extraReducers: (builder) => {
        builder.addCase(fetchAccountBank.pending, (state: InitialState) => {
            console.log('fetchAccountBank pending')
            state.creatTime = 'loading...'
        });
        builder.addCase(fetchAccountBank.fulfilled, (state, action) => {
            console.log(action.payload)
            state.creatTime = action.payload;
            console.log('fetchAccountBank fulfilled')
        });
        builder.addCase(fetchAccountBank.rejected, (state) => {
            console.log('fetchAccountBank rejected')
            state.creatTime = 'failed...'
        })
    }
})

export const {updateBankAccount, updateBankAmount,} = slice.actions;
export default slice.reducer;

因为Typescript语言有较强的类型校验,在异步时dispatch报错,如下

只需在使用useDispatch时,声明泛型类型即可。

    // 异步需声明useDispatch类型
    const asyncDispatch = useDispatch<AppDispatch>();

最佳实践全部代码如下:

ReduxToolkit+TypeScript最佳实践资源-CSDN文库

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【GO语言卵细胞级别教程】11.探索Go语言的面向对象编程之美(含源码仅此一份,先到先得)

【GO语言卵细胞级别教程】11.探索Go语言的面向对象编程之美&#xff08;含源码仅此一份&#xff0c;先到先得&#xff09; 目录 【GO语言卵细胞级别教程】11.探索Go语言的面向对象编程之美&#xff08;含源码仅此一份&#xff0c;先到先得&#xff09;1.面向对象的引用1.1简介1…

Day79:服务攻防-中间件安全IISApacheTomcatNginx弱口令不安全配置CVE

目录 中间件-IIS-短文件&文件解析&蓝屏&写权限 HTTP.SYS&#xff08;CVE-2015-1635&#xff09;主要用作蓝屏破坏&#xff0c;跟权限不挂钩 IIS短文件(iis全版本都可能有这个问题) IIS文件解析 IIS写权限 中间件-Nginx-文件解析&目录穿越漏洞&CRLF …

C++ //练习 11.14 扩展你在11.2.1节练习(第378页)中编写的孩子姓到名的map,添加一个pair的vector,保存孩子的名和生日。

C Primer&#xff08;第5版&#xff09; 练习 11.14 练习 11.14 扩展你在11.2.1节练习&#xff08;第378页&#xff09;中编写的孩子姓到名的map&#xff0c;添加一个pair的vector&#xff0c;保存孩子的名和生日。 环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#x…

【大数据存储】实验七 Spark RDD

Spark RDD操作实验 一、实验目的 &#xff08;1&#xff09;掌握使用Spark访问本地文件和HDFS文件的方法 &#xff08;2&#xff09;熟练掌握在Spark Shell中对Spark RDD的操作方法 &#xff08;3&#xff09;掌握Spark应用程序的编写、编译打包和运行方法 二、.实验平台 …

自动化测试框架Robot Framework入门

什么是RF RF是一个基于 Python 的、可扩展的关键字驱动的自动化 验收测试框架、验收测试驱动开发 &#xff08;ATDD&#xff09;、 行为驱动开发 &#xff08;BDD&#xff09; 和机器人流程自动化 &#xff08;RPA&#xff09;。它 可用于分布式、异构环境&#xff0c;其中自动…

VUE3和SpringBoot实现ChatGPT页面打字效果SSE流式数据展示

在做这个功能之前&#xff0c;本人也是走了很多弯路&#xff08;花了好几天才搞好&#xff09;&#xff0c;你能看到本篇博文&#xff0c;那你就是找对地方了。百度上很多都是使用SseEmitter这种方式&#xff0c;这种方式使用的是websocket&#xff0c;使用这种方式就搞复杂了&…

STM32 PWM方式读取AS5600磁编码器数据

HAL STM32 PWM方式读取AS5600磁编码器获取角度例程 &#x1f4cd;相关篇《STM32 软件I2C方式读取AS5600磁编码器获取角度例程》 &#x1f4cc;《HAL STM32 硬件I2C方式读取AS5600磁编码器获取角度例程》 &#x1f341;先通过IIC读取的角度值和逻辑分析仪抓取的AS5600 OUT引脚…

MySQL - 基础二

6、表的增删改查 CRUD : Create(创建), Retrieve(读取)&#xff0c;Update(更新)&#xff0c;Delete&#xff08;删除&#xff09; 6.1、Create 语法&#xff1a; INSERT [INTO] table_name[(column [, column] ...)]VALUES (value_list) [, (value_list)] ...value_list: v…

SQL注入---盲注

文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 一.盲注概述 注是一种SQL注入攻击的形式&#xff0c;在这种攻击中&#xff0c;攻击者向目标应用程序发送恶意注入代码&#xff0c;然后通过观察应用程序的响应来推断出数据库中的信息。与常规的…

@Order和@DependsOn的区别

这里写自定义目录标题 一、区别二、demo演示1、Order2、DependsOn 一、区别 Order&#xff1a;改变Bean注入的顺序DependsOn&#xff1a;改变Bean创建的顺序 二、demo演示 1、Order 类 A B 都实现了接口 I &#xff0c;且 A B都由Spring容器创建并且管理 public class A im…

【Qt】:常用控件(二:QWidget核心属性)

常用控件&#xff08;二&#xff09; 一.cursor&#xff08;光标形状&#xff09;二.font&#xff08;字体信息&#xff09;三.toolTip&#xff08;提示显示&#xff09;四.focusPolicy&#xff08;焦点&#xff09;五.styleSheet&#xff08;文本样式&#xff09; 一.cursor&a…

Windows Docker 部署 Firefly III 开源记账软件

一、简介 Firefly III是一款开源的记账软件&#xff0c;支持全球多种语言。它可以帮助用户追踪和管理个人账目、预算和账单&#xff0c;减少支出&#xff0c;节省更多。该软件支持多种货币、银行账户和投资账户&#xff0c;并提供了丰富的报表功能&#xff0c;帮助用户更好地了…

预处理指令详解

前言 上一节我们了解了文件操作的相关内容&#xff0c;本节我们来了解一下预处理指令&#xff0c;那么废话不多说&#xff0c;我们正式开始今天的学习 预定义符号 在C语言中&#xff0c;设置了一些预定义的符号&#xff0c;可以供我们直接使用&#xff0c;预定义符号是在程序…

拓扑排序--有向无环图中一个节点的所有祖先

题目描述 给你一个正整数 n &#xff0c;它表示一个 有向无环图 中节点的数目&#xff0c;节点编号为 0 到 n - 1 &#xff08;包括两者&#xff09;。 给你一个二维整数数组 edges &#xff0c;其中 edges[i] [fromi, toi] 表示图中一条从 fromi 到 toi 的单向边。 请你返…

基于SpringBoot和Vue的金融融资管理系统的设计和实现【附源码】

1、系统演示视频&#xff08;演示视频&#xff09; 2、需要交流和学习请联系

图像处理入门 3(how to get the pixel pitch / 如何获得单个像素的尺寸)

在这里一节里面&#xff0c;将记录如何获得一个相机传感器中单个像素点的尺寸&#xff0c;为了实现不同相机照片之间的匹配。 如果我们知道了相机传感器的尺寸和分辨率的大小&#xff0c;自然就可以求出单个像素的大小。 在这里插入图片描述&#xff1a; 如何获得相机传感器的…

读《Spring实战》:面向切面

AOP术语 通知&#xff08;Advice&#xff09; 在AOP中&#xff0c;切面的工作被称为通知&#xff0c;也就是通知就是具体要干的工作。 spring中有5中通知&#xff1a; 前置通知&#xff1a; 在目标方法之前调用通知功能后置通知&#xff1a; 在目标方法之后调用通知功能返回…

SQL Server维护计划

目录 1.概述 2.启动SQL Server 代理服务 3.制定维护计划 4.验证维护计划 5.删除维护计划 1.概述 此文还是存货哈&#xff01; SQL Server 2008 R2维护计划。 2.启动SQL Server 代理服务 在设置维护计划之前&#xff0c;必须先确保SQL Server 代理服务已启动。启动方法如…

FastAPI Web框架教程 第12章 异步async-await

12-1 fastapi是异步Web框架 从本教程开篇&#xff0c;我们就说FastAPI这个web框架是异步框架&#xff0c;那它到底是如何体现异步的呢&#xff1f; 想要学习使如何使用FastAPI的异步功能&#xff0c;那就必须要先了解什么是异步&#xff0c;什么是asyncio、async/await 【基…

BoostCompass —— 搜索引擎

文章目录 一、项目简介二、Boost库简介1. 简介2. Boost 库的特点 三、项目主要模块1. 网页内容获取&#xff0c;数据预处理模块2. 建立正排索引和倒排索引&#xff0c;项目核心模块3. 编写 http_server 模块&#xff0c;进行网络开放 四、项目功能预览1. 项目文件预览2. 项目执…