React | 再战Redux

news2024/12/24 8:39:07

✨ 个人主页:CoderHing

🖥️ React.js专栏:React.js 再战Redux
🙋‍♂️ 个人简介:一个不甘平庸的平凡人🍬

💫 系列专栏:吊打面试官系列  16天学会Vue  7天学会微信小程序  Node专栏

🍀 格言: ☀️ 路漫漫其修远兮,吾将上下而求索☀️

👉 你的一键三连是我更新的最大动力!❤️

❤️ 本文约 3000  字,预计阅读需要 15 分钟 ❤️


目录

一、认识ReduxToolkit

认识Redux Toolkit

二、ReduxToolkit重构

重构代码 – 创建counter的reducer

重构代码 – 创建home的reducer

store的创建

三、ReduxToolkit异步

Redux Toolkit的异步操作

extraReducer的另外一种写法

Redux Toolkit的数据不可变性

四、connect高阶组件

自定义connect函数,context处理store

五、中间件的实现原理

打印日志的需求

修改dispatch

thunk需求

合并中间件

六、React状态管理选择

React中的state如何管理


一、认识ReduxToolkit

认识Redux Toolkit

  • Redux Toolkit 是官方推荐的编写 Redux 逻辑的方法

    • 在前面我们学习Redux的时候应该已经发现,redux的编写逻辑过于的繁琐和麻烦

    • 并且代码通常分拆在多个文件中(虽然也可以放到一个文件管理,但是代码量过多,不利于管理)

    • Redux Toolkit包旨在成为编写Redux逻辑的标准方式,从而解决上面提到的问题

    • 在很多地方为了称呼方便,也称为"RTK"

  • 安装Redux Toolkit:

    • Npm install @reduxjs/toolkit react-redux

  • Redux Toolkit的核心API主要有以下几个:

    • configureStore:包装createStore以提供简化的配置选项和良好的默认值.它可以自动组合你的slice reducer,添加你提供的任何Redux中间件,redux-thunk默认包含,并启用Redux DevTools Extension

    • createSlice:接收reducer函数的对象,切片名称和初始状态值,并自动生成切片reducer,并带有相应的actions

    • createAsyncThunk:接收一个动作类型字符串和一个返回承诺的函数,并生成一个pending/fulfilled/rejected基于该承诺分派动作类型的 thunk

二、ReduxToolkit重构

重构代码 – 创建counter的reducer

  • 我们先对counter的reducer进行重构:通过createSlice创建一个slice

  • createSlice主要包含如下几个参数:

  • name:用户标记slice的名词

    • 在之后的redux-devtool中会显示对应的名词

  • initialState:初始化值

    • 第一次初始化时的值

  • reducers:相当于之前的reducer函数

    • 对象类型,并且可以添加很多的函数

    • 函数类似于redux原来reducer中的一个case语句

    • 函数的参数:

      • 参数一:state

      • 参数二:调用这个action时,传递的action参数

  • createSlice返回值是一个对象,包含所有的actions

重构代码 – 创建home的reducer

store的创建

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

    • reduce:将slice中的reducer可以组成一个对象传入此处

    • middleware:可以使用参数,传入其他的中间件(自行了解)

    • devTools:是否配置devTools工具,默认为true

三、ReduxToolkit异步

 

Redux Toolkit的异步操作

  • 在之前的开发中,我们通过redux-thunk中间件让dispatch中可以进行异步操作

  • Redux Toolkit默认已经给我们集成了Thunk相关的功能:createAsyncThunk

  • 当createAsyncThunk创建出来的action被dispatch时,会存在三种状态:

    • pending:action被发出,但是还没有最终的结果

    • fulfilled:获取到最终的结果(有返回值的结果)

    • rejected:执行过程中有错误或者抛出了异常

  • 我们可以在createSlice的entraReducer中监听这些结果:

extraReducer的另外一种写法

  • extraReducer还可以传入一个函数,函数接收一个builder参数

    • 我们可以向builder中添加case来监听异步操作的结果:

Redux Toolkit的数据不可变性

  • 在React开发中,我们总是会强调数据的不可变性:

    • 无论是类组件中的state,还是redux中管理的state

    • 事实上在整个JavaScript编码过程中,数据的不可变性都是非常重要的

  • 所以在前面我们经常会进行浅拷贝来完成某些操作,但是浅拷贝事实上也是存在问题的:

    • 比如过大的对象,进行浅拷贝也会造成性能的浪费

    • 比如浅拷贝后的对象,在深层改变时,依然会对之前的对象产生影响

  • 事实上Redux Toolkit底层使用了immerjs的一个库来保证数据的不可变性

  • 为了节约内存,又出现了一个新的算法:Persistent Data Structure(持久化数据结构或一致性数据结构)

    • 用一种数据结构来保存数据

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

四、connect高阶组件

自定义connect函数,context处理store

 

五、中间件的实现原理

打印日志的需求

  • 中间件的目的是在redux中插入一些自己的操作:

    • 比如我们现在有一个需求,在dispatch之前,打印一下本次的action对象,dispatch完成之后可以打印一下最新的store state

    • 也就是我们需要将对应的代码插入到redux的某部分,让之后所有的dispatch都可以包含这样的操作

  • 如果没有中间件,我们是否可以实现类似的代码呢?可以在派发的前后进行相关的打印

  • 但是这种方式缺陷非常明显:

    • 首先,每一次的dispatch操作,我们都需要在前面加上这样的逻辑代码

    • 其次,存在大量重复的代码,会非常麻烦和臃肿

  • 是否有一种更优雅的方式来处理这样的相同逻辑呢?

    • 我们可以将代码封装到一个独立的函数中

  • 但是这样的代码有一个非常大的缺陷:

    • 调用者(使用者)在使用我的dispatch时,必须使用我另外封装的一个函数dispatchAndLog;

    • 显然,对于调用者来说,很难记住这样的API,更加习惯的方式是直接调用dispatch;

修改dispatch

  • 事实上,我们可以利用一个hack一点的技术:Monkey Patching,利用它可以修改原有的程序逻辑

  • 我们对代码进行如下的修改:

    • 这样就意味着我们已经直接修改了dispatch的调用过程

    • 在调用dispatch的过程中,真正调用的函数其实是dispatchAndLog

  • 我们可以将它封装到一个模块中,只要调用这个模块中的函数,就可以对store进行这样的处理:

thunk需求

  • redux-thunk的作用:

    • 我们知道redux中利用一个中间件redux-thunk可以让我们的dispatch不再只是处理对象,并且可以处理函数;

    • 那么redux-thunk中的基本实现过程是怎么样的呢?事实上非常的简单。

  • 我们来看下面的代码:

    • 我们又对dispatch进行转换,这个dispatch会判断传入的

合并中间件

  • 单个调用某个函数来合并中间件并不是特别的方便,我们可以封装一个函数来实现所有的中间件合并:

  •  

  • 我们来理解一下上面操作之后,代码的流程

  • 当然,真实的中间件实现起来会更加的灵活,这里我们仅仅做一个抛砖引玉,有兴趣可以参考redux合并中间件的源码流程

六、React状态管理选择

React中的state如何管理

  • 我们学习了Redux用来管理我们的应用状态,并且非常好用(当然,你学会前提下,没有学会,好好回顾一下)

  • 目前我们已经主要学习了三种状态管理方式:

    • 方式一:组件中自己的state管理

    • 方式二:Context数据的共享状态

    • 方式三:Redux管理应用状态

  • 在开发中如何选择呢?

    • 首先,这个没有一个标准的答案

    • 某些用户,选择将所有的状态放到redux中进行管理,因为这样方便追踪和共享

    • 有些用户,选择将某些组件自己的状态放到组件内部进行管理

    • 有些用户,将类似于主题、用户信息等数据放到Context中进行共享和管理

    • 做一个开发者,到底选择怎样的状态管 理方式,是你的工作之一,可以一个最好的平衡方式(Find a balance that works for you, and go with it.)

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

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

相关文章

chatgpt赋能python:下载Python的方法及使用指南

下载Python的方法及使用指南 Python是一种高级编程语言,被广泛应用于各种领域。如果你是一名程序员或者对编程有兴趣,那么学习Python会是一个不错的选择。本文将介绍Python的下载方法,并提供使用Python的基础指南。 Python的下载方法 Pyth…

Istio与Mcp Server服务器讲解与搭建演示

01Istio与外部注册中心 Istio为何需要对接外部注册中心 Istio 对 Kubernetes 具有较强的依赖性: 1.服务发现就是基于 Kubernetes 实现的,如果要使用 Istio,首先需要迁移到 Kubernetes 上,并使用 Kubernetes 的服务注册发现机制…

【数据挖掘】时间序列教程【二】

2.4 示例:颗粒物浓度 在本章中,我们将使用美国环境保护署的一些空气污染数据作为运行样本。该数据集由 2 年和 5 年空气动力学直径小于或等于 3.2017 \(mu\)g/m\(^2018\) 的颗粒物组成。 我们将特别关注来自…

认识GCC

GNU GNU是Linux系统下的一些工具包,GNU是GNU is Not Unix的缩写,因为当年Unix收费后,理查德马修斯托曼打算做一套GNU操作系统,当时GNU的工具包已经写好,就差内核即可组装成一个完整的操作系统,正好Linux写…

跨链 vs 多链

跨链 dApp 可以在部署在多个不同区块链上的多个不同智能合约上运行,而多链 dApp 则可以在不同网络上以多个单独的版本部署。 由于对区块空间的需求不断增加,Web3 应用层现在存在于数百个不同的区块链、二层网络和应用链上。这种现实催生了两个新术语——…

【教程】解决php微擎中的goto加密解密,一键解密工具

今天,我将向大家揭秘一款神奇的工具——goto解密工具,轻松解密这个看似棘手的问题。 无数开发者都曾因为php中的goto功能而头疼不已。goto解密工具其中之一就是解密goto代码。通过精妙的算法和强大的解析能力,它能够解密被goto加密的代码段&…

Vue项目设置网站小徽标

一、预期效果 自定义Vue项目的网站小徽标,用于显示网站的logo,效果大致如下 二、制作 .ico文件 2.1 打开比特虫官网 比特虫官网:https://www.bitbug.net/ 2.2 操作步骤如图 三、引入Vue项目 3.1 将生成的 .ico文件放入我们的 Vue 项目 3.…

servlet+JSP与SpringBoot+Vue项目交互——servlet请求SpringBoot接口

问题 servletJSP与SpringBootVue项目交互——servlet请求SpringBoot接口 详细问题 笔者前一段时间开发一个项目,使用的技术框架是servletJSP,现阶段开发的项目技术框架为SpringBootVue,笔者现在需要输入servletJSP请求SpringBoot接口&…

C语言编程—递归

递归指的是在函数的定义中使用函数自身的方法。 举个例子:从前有座山,山里有座庙,庙里有个老和尚,正在给小和尚讲故事呢!故事是什么呢?"从前有座山,山里有座庙,庙里有个老和尚&…

2024考研408-计算机组成原理第六章-总线学习笔记

文章目录 前言初识总线一、总线概述1.1、总线的概述1.1.1、认识总线1.1.2、设计总线需要的特性1.1.3、总线的分类①按照数据传输格式分(串行、并行)②按照总线功能连接的总线(片内总线、系统总线、通信总线)③按照时序控制方式&am…

css新特性(五)

css基础(一)css基础(一)_上半场结束,中场已休息,下半场ing的博客-CSDN博客Emmet语法Emmet语法_上半场结束,中场已休息,下半场ing的博客-CSDN博客css基础(二)c…

Retrofit注解

1. 注解类型 Retrofit路径结合的规则 2. 网络请求方法 2.1 Get请求 完整地址:http://mock-api.com/2vKVbXK8.mock/getUserInfo?iduserid 2.1.1 Query 创建Retrofit实例必须传入baseurl(http://mock-api.com/2vKVbXK8.mock/),在GET("getUserIn…

Android跨平台语言分析

跨平台技术发展的三个阶段 第一阶段是混合开发的web容器时代 为了解决原生开发的高成本、低效率,出现了Hybrid混合开发原生中嵌入依托于浏览器的WebViewWeb浏览器中可以实现的需求在WebView中基本都可以实现但是Web最大的问题是,它的性能和体验与原生开发…

Mybatis面试题--MyBatis执行流程

首先我们知道Mybatis是目前最流行的持久层框架,当我们了解了执行流程,可以让我们理解各个组件的关系,以及Sql的执行过程(参数映射、sql解析、执行和结果处理) 1首先我们需要读取框架的核心配置文件 2接下来我们就要去操…

chatgpt赋能python:Python编程的好玩儿之处:介绍几个有趣的Python程序

Python编程的好玩儿之处:介绍几个有趣的Python程序 Python已经成为了一种非常受欢迎的编程语言,除了其在Web开发和数据科学领域的应用,它还能够完成很多好玩儿的事情!接下来,我将介绍几个有趣的Python程序&#xff0c…

【零基础入门学习Python---Python多线程和多进程】

🚀 Python 🚀 🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀 🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨ 🌲 作者简介:硕风和炜,…

基于SpringBoot+vue前后端分离的相机销售系统

文章目录 项目介绍主要功能截图:首页相机详情个人中心 部分代码展示设计总结项目获取方式 🍅 作者主页:Java韩立 🍅 简介:Java领域优质创作者🏆、 简历模板、学习资料、面试题库【关注我,都给你…

Centos7.9 磁盘分区、挂载

常用命令: fdisk /dev/vdb 创建分区 mkfs.ext2 /dev/vdb3 文件系统(ext2,ext4,xfs)格式化 mkfs.ext4 /dev/vdb3 mkfs.xfs /dev/vdb3 df -T 命令查看格式化是否成功(要先把分区挂载到目录,否则df…

18. WebGPU 计算着色器

本文接续基础知识文章。我们将从一些基本的计算着色器开始&#xff0c;然后希望继续讨论解决现实世界问题并写一些示例。 在上一篇文章中&#xff0c;制作了一个非常简单的计算着色器&#xff0c;可以将数字加倍。 这是着色器 group(0) binding(0) var<storage, read_wri…

Java安装

Java Downloads | Oracle 一直往下拉 配置环境变量 第二部分&#xff1a;idea旗舰版下载安装配置 1. 字号 file-settings-editor-font-23 &#xff0c;还有菜单字号