React-Redux(二)

​🌈个人主页:前端青山
🔥系列专栏:React篇
🔖人终将被年少不可得之物困其一生

依旧青山,本期给大家带来React篇专栏内容:React-Redux(二)

目录

react-redux

模块化

redux-thunk

react-redux

网址:React Redux | React Redux

React-Redux是Redux的官方针对React开发的扩展库,默认没有在React项目中安装,需要手动来安装。react-redux是依赖于redux,所以必须先安装redux。

我们可以理解为react-redux就是redux给我们提供的高阶组件加工厂。

npm i -S react-redux

React-redux所能解决的问题是:

  • 使用它以后我们不需要在每个组件中再去 手动订阅数据的更新了。

  • 没有了数据的初始化state赋值,当前组件自身state和这个redux不冲突了

  • 使用本节的react-redux与下一节的redux-thunk并不是为了简化代码的,它们存在的意义是解决前面所遇到的问题

使用步骤

  • 在项目入口文件中定义Provider

    • 该步骤的操作有点类似于之前组件通信中的context那块的操作

    • 将整个仓库作为商品提供给App根组件,后续的所有的组件都可以获取到仓库store中的数据

    • 注意:与context不一样,这里绑定数据使用的属性是“store”

    • src/index.js文件中的示例代码:

      // 导入
      import React from "react";
      import ReactDOM from "react-dom";
      // 导入provider
      import { Provider } from "react-redux";
      import store from "./store/index";
      ​
      // 导入需要展示的组件
      import App from "./Login";
      ​
      // 渲染视图
      // 在展示app组件的时候需要按照组件的形式进行操作
      ReactDOM.render(
          <Provider store={store}>
              <App></App>
          </Provider>
          document.getElementById("root")
      );

  • 在需要使用redux的组件中使用

    • 这个步骤与vuex中map系列函数(mapState,mapMutations,mapActions、mapGetters)的思想是一样的

    • 思想:将仓库中的属性和方法映射成当前组件自身的属性和方法

    • 在实际使用的时候组件中不再需要使用store对象了(包括初始的获取数据:store.getState()、store.dispatch()、store.subscribe())

    • 步骤

      • 在需要使用reudx的组件前面导入react-redux提供的高阶组件:connect

      • 编写映射方法(请注意,这个方法映射不是类组件的方法,而是在类组件外写的方法)

        • mapStateToProps(state)

          • 作用:将仓库中的state数据源映射成本组件的属性props,返回一个props对象

          • 参数:仓库中的state

        • mapDispatchToProps(dispatch)

          • 作用:将派发action的方法映射成当前组件自身的属性,该方法也要求返回一个对象,该对象中存放的就是派发action的方法集合

          • 参数:dispatch如同之前的store.dispatch()

        • 编写时,可以写箭头函数,也可以写常规函数

      • 应用高阶组件connect,写法是固定的

        • // 在组件最后导出的时候改写成如下:
          export default connect(mapStateToProps,mapDispatchToProps)(ComponentName)
    • 组件中实际使用时的参考代码:以jsx为例

      import React, { Component } from "react";
      // 需要导入store
      // import store from "../store/index";
      // 导入action创建模块(导出里面全部的方法)
      import * as actionCreate from "../store/actions/index";
      // 导入type
      import { MOD_COUNT, MOD_AGE } from "../store/types/index";
      // import * as types from "../store/types/index";
      ​
      // 第一步:在需要使用redux组件中导入一个由react-redux提供的hoc
      import { connect } from "react-redux";
      class Counter extends Component {
          // 在constructor中获取store中的数据
          constructor(props) {
              super(props);
              // 获取store数据(一次性,不具备响应式)
              // this.state = store.getState();
              // 订阅数据的更新
              // store.subscribe(() => this.setState(() => store.getState()));
          }
          render() {
              console.log(this.state);
              return (
                  <div>
                      <div>当前Store中的数据是:{this.props.tool.count}</div>
                      <button onClick={this.props.addCount}>点击+9</button>
                      <hr />
                      <div>当前Store中的数据是:{this.props.user.age}</div>
                      <button onClick={this.props.addAge}>点击+1</button>
                  </div>
              );
          }
      }
      ​
      // 第二步:在类外面定义俩个映射方法
      // 将redux中的state数据源映射到本组件自身的props中
      function mapStateToProps(state) {
          // return state.user;
          // return state.tool;
          return state;
      }
      // 将dispatch映射成自身组件的props
      function mapDispatchToProps(dispatch) {
          // 该方法返回一个对象,对象中都是方法
          return {
              addCount() {
                  dispatch(actionCreate.createAction(MOD_COUNT, 9));
              },
              addAge() {
                  dispatch(actionCreate.createAction(MOD_AGE, 1));
              },
          };
      }
      ​
      // 第三步:应用HOC
      // connect函数的俩个参数顺序不能颠倒
      export default connect(mapStateToProps, mapDispatchToProps)(Counter);

模块化

如果redux需要使用多个模块,请使用combineReducers方法将多个reudcer函数进行组合,得到一个根reducer对象,将对象传递给创建仓库的方法:Redux Fundamentals, Part 3: State, Actions, and Reducers | Redux

针对redux的模块化,在一个常规项目中会将其代码拆分成以下几个部分:

  • Reducers,建立同名目录,存放模块化之后的reducer

  • Actions:建立同名目录,存放模块化之后的action

  • Type(可选):建立同名目录,存放独立的type声明

具体实现,以项目的代码为准。

面试题:如果项目有100甚至更多个reducer模块,后续就得import100次甚至更多次,虽然代码简单,但是很繁琐,请问如何优化?

// 代码优化,批量导入
const files = require.context("./reducers", false, /\.js$/);
// 比较固定的处理代码
let members = {}; // 组合成员用的
files.keys().forEach((element) => {
     // element是对应的模块文件的路径
     console.log(element);
     // 依据路径获取导出的成员
     let member = files(element).default;
     // 获取文件名充当对象的属性名
     let filename = element.replace(/(.*\/)*([^.]+).*/gi, "$2");
     // 组合成员
     members[filename] = member;
 });
console.log(members);

redux-thunk

通常情况下,action只是一个对象,不能包含异步操作,这导致了很多创建action的逻辑只能写在组件中,代码量较多也不便于复用,同时对该部分代码测试的时候也比较困难,组件的业务逻辑也不清晰,使用中间件了之后,可以通过actionCreator异步编写action,这样代码就会拆分到actionCreator中,可维护性大大提高,可以方便于测试、复用,同时actionCreator还集成了异步操作中不同的action派发机制,减少编码过程中的代码量。

常见的异步库:

  • Redux-thunk

  • Redux-saga

  • Redux-effects

  • Redux-side-effects

  • Redux-loop

  • Redux-observable

基于Promise的异步库:

  • Redux-promise

  • Redux-promises

  • Redux-simple-promise

  • Redux-promise-middleware

这里我们使用一个Redux官方出品的中间件库:redux-thunk

在使用前需要先安装这个中间件:

npm i -S redux-thunk

步骤:

  • 在仓库的创建文件store/index.js文件中导入中间件的应用方法,再去导入redux-thunk,并且应用

    • 导入redux提供的中间件使用的方法:applyMiddleware

  • 会产生报错(浏览器的redux调试工具的报错)需要解决

    • 解决思路:查看

      [插件的项目主页]  https://github.com/zalmoxisus/redux-devtools-extension#usage 

      ,找解决办法

      修改为的配置如下:

      // 解决插件报错的操作
      const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
      ​
      const store = createStore(
          // 合并多个reducer(整合数据源),不合并会报错
          combineReducers({ counter, global }),
          // 应用中间件
          composeEnhancers(applyMiddleware(thunk))
          // 必须要加上一段插件的配置工具,才能在浏览器中使用redux扩展
          // window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
      );

  • 去需要做异步处理的action的位置去使用异步实现(通过dispatch派发action)

    • // - 异步方法(载荷可能是异步获取的数据)
      export const createActionAsync = (type, payload) => {
          // 异步代码先不写(暂时没有异步中间件)
          // return { type, payload };
          // setTimeout(() => {
          //     return { type, payload };
          // }, 1000);
      ​
          // 异步写法
          return (dispatch) => {
              setTimeout(() => {
                  dispatch({ type, payload });
              }, 3000);
          };
      };

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

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

相关文章

【pyhon】while语句的题目

1.计算1至100的偶数之和 sum_even 0 # 初始化偶数之和为0 i 1 # 从1开始循环 while i < 100: # 当i小于或等于100时&#xff0c;继续循环 if i % 2 0: # 如果i是偶数 sum_even i # 将i加到偶数之和上 i 1 # i自增1 print(“1至100的偶数之和为:”, sum_even) 给出乘…

SpringBoot源码解析-02

5. 模板引擎 由于 SpringBoot 使用了嵌入式 Servlet 容器 (tomca)。所以 JSP 默认是不能使用的。如果需要服务端页面渲染&#xff0c;优先考虑使用 模板引擎。 模板引擎页面默认放在 src/main/resources/templates SpringBoot 包含以下模板引擎的自动配置 FreeMarkerGroov…

Java NIO,高效操作I/O流的必备技能

Java IO在工作中其实不常用到&#xff0c;更别提NIO了。但NIO却是高效操作I/O流的必备技能&#xff0c;如顶级开源项目Kafka、Netty、RocketMQ等都采用了NIO技术&#xff0c;NIO也是大多数面试官必考的体系知识。虽然骨头有点难啃&#xff0c;但还是要慢慢消耗知识、学以致用哈…

设计模式:观察者模式(Observer)

设计模式&#xff1a;观察者模式&#xff08;Observer&#xff09; 设计模式&#xff1a;观察者模式&#xff08;Observer&#xff09;模式动机模式定义模式结构时序图模式实现观察者模式在单线程环境下的测试观察者模式在多线程环境下的测试多线程下的观察者模式模式分析优缺点…

计算机不联网是否有IP地址

计算机不联网是否会有IP地址&#xff0c;这个问题涉及到计算机网络的基础知识。要深入探讨这个问题&#xff0c;我们需要从IP地址的定义、作用&#xff0c;以及计算机在不联网状态下的网络配置等多个方面进行分析。 首先&#xff0c;IP地址&#xff08;Internet Protocol Addre…

HCIA--综合实验(超详细)

要求&#xff1a; 1. 使用172.16.0.0/16划分网络 2.使用ospf协议合理规划区域保证更新安全 3.加快收敛速度 4. r1为DR没有BDR 5.PC2&#xff0c;3&#xff0c;4&#xff0c;5自动获取IP地址&#xff1b;PC1为外网&#xff0c;PC要求可用互相访问 6.r7为运营商&#xff0c;只能配…

Oracle 正则,开窗,行列转换

1.开窗函数 基本上在查询结果上添加窗口列 1.1 聚合函数开窗 基本格式: ..... 函数() over([partition by 分组列,...][order by 排序列 desc|asc][定位框架]) 1&#xff0c;partition by 字段 相当于group by 字段 起到分组作用2&#xff0c;order by 字段 即根据某个字段…

Java实现优先级队列(堆)

前言 在学习完二叉树的相关知识后&#xff0c;我们对数据结构有了更多的认识&#xff0c;本文将介绍到优先级队列(堆&#xff09; 1.优先级队列 1.1概念 前面介绍过队列&#xff0c;队列是一种先进先出(FIFO)的数据结构&#xff0c;但有些情况下&#xff0c;操作的数据可能…

万兆以太网MAC设计(1)10G PCS PMA IP核使用

文章目录 一、设计框图二、模块设计三、IP核配置四、上板验证五、总结 一、设计框图 关于GT高速接口的设计一贯作风&#xff0c;万兆以太网同样如此&#xff0c;只不过这里将复位逻辑和时钟逻辑放到了同一个文件ten_gig_eth_pcs_pma_0_shared_clock_and_reset当中。如果是从第…

将图片按灰度转换成字符

from struct import *ch [., :, !, ~, ,, ^, *,$, #] ch.reverse()def calc(R, G, B):#模式Lreturn R * 299 // 1000 G * 587 // 1000 B * 144 / 1000def character( val):num val / 260 * len(ch)num round(num)if num>len(ch):numlen(ch)-1return ch[num]class rmb:d…

浅谈Spring的Bean生命周期

在Spring框架中&#xff0c;Bean&#xff08;即Java对象&#xff09;的生命周期涵盖了从创建到销毁的全过程&#xff0c;主要包含以下几个阶段&#xff1a; 实例化&#xff08;Instantiation&#xff09;&#xff1a; 当Spring IoC容器需要创建一个Bean时&#xff0c;首先会通过…

【安全设备】Hfish如何测试

部署好了蜜罐如何测试&#xff1f; 1、查找节点 2、节点的端口 3、将部署的主机和节点联系在一起 http访问。 就可以测试了。

Win10系统VScode远程连接VirtualBox安装的Ubuntu20.04.5

1.打开虚拟机&#xff0c;在中端中输入命令: sudo apt-get install openssh-server 安装ssh 我这里已经安装完成&#xff0c;故显示是这样 2.输入命令&#xff1a;sudo systemctl start ssh 启动远程连接 注意&#xff0c;如果使用VirtualBox安装的虚拟机&#xff0c;需要启用…

Git分布式版本控制系统——在IDEA中使用Git(一)

一、在IDEA中配置Git 本质上还是使用的本地安装的Git软件&#xff0c;所以需要在IDEA中配置Git 打开IDEA的设置页面&#xff0c;按照下图操作 二、在IDEA中使用Git获取仓库 1、本地初始化仓库 2、从远程仓库克隆 方法一&#xff1a; 方法二&#xff1a; 三、.gitignore文件…

测绘管理与法律法规 | 测绘资质分类分级标准 | 学习笔记

目录 1. 申请条件 2.审批程序 3.专业技术人员的特殊规定 1. 申请条件 法人资格&#xff1a;申请单位必须具有法人资格。 专业技术人员&#xff1a;需拥有与测绘活动相适应的测绘专业技术人员和相关专业技术人员。 技术装备&#xff1a;具备与测绘活动相适应的技术装备和设…

js-利用blur使文本框自动控制格式

在 JavaScript 中&#xff0c;blur 是一个事件&#xff0c;它在一个元素失去焦点时触发。当用户从一个元素中移开或者将焦点转移到页面上的另一个元素时&#xff0c;该元素将触发 blur 事件。这个事件通常用于验证用户输入或执行其他与用户交互相关的操作。 假设我有个文本框&…

工业物联网让“制造”变成“智造”!——青创智通

工业物联网解决方案-工业IOT-青创智通 随着科技的不断进步和工业的持续发展&#xff0c;物联网&#xff08;IoT&#xff09;技术的出现为制造业带来了前所未有的变革。工业物联网&#xff08;IIoT&#xff09;作为物联网技术在工业领域的应用&#xff0c;正在逐渐改变传统的制…

Netty学习——高级篇2 Netty解码技术

接上篇&#xff1a;Netty学习——高级篇1 拆包 、粘包与编解码技术&#xff0c;本章继续介绍Netty的其他解码器 1 DelimiterBasedFrameDecoder分隔符解码器 DelimiterBasedFrameDecoder 分隔符解码器是按照指定分隔符进行解码的解码器&#xff0c;通过分隔符可以将二进制流拆分…

数据的插入、修改和删除

一、 插入数据 1. 向表中所有字段插入数据 &#xff08;1&#xff09; 指定所有字段及其相对应的值 insert into 表名(字段1&#xff0c;字段2&#xff0c;……) values(字段值1&#xff0c;字段值2&#xff0c;……);**【案例】**向goods表中插入一条新记录 步骤1&#xff…

密码学 | 椭圆曲线数字签名方法 ECDSA(上)

目录 1 ECDSA 是什么&#xff1f; 2 理解基础知识 3 为什么使用 ECDSA&#xff1f; 4 基础数学和二进制 5 哈希 6 ECDSA 方程 7 点加法 8 点乘法 9 陷阱门函数&#xff01; ⚠️ 原文&#xff1a;Understanding How ECDSA Protects Your Data. ⚠️ 写在前面…