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);};
      };

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

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

相关文章

ArcGIS加载的各类地图怎么去除服务署名水印

昨天介绍的&#xff1a; 一套图源搞定&#xff01;清新规划底图、影像图、境界、海洋、地形阴影图、导航图-CSDN博客文章浏览阅读373次&#xff0c;点赞7次&#xff0c;收藏11次。一体化集成在一起的各类型图源&#xff0c;比如包括影像、清新的出图底图、地形、地图阴影、道路…

富文本回显 p 标签?去不掉怎么办?如何解决?

使用前端框架富文本控件上传的上传的数据&#xff0c;回显到文本框时显示<p></p>标签&#xff0c;并且数据库里面的数据也为带有p标签的数据&#xff0c;如何去掉 解决办法 使用正则表达式来讲HTML的内容进行替换更改&#xff0c;在vue中定义方法 //移除HTML标签…

Axure实现导航栏的展开与收缩

Axure实现导航栏的展开与收缩 一、概要介绍二、设计思路三、Axure制作导航栏四、技术细节五、小结 一、概要介绍 使用场景一般是B端后台系统需要以导航栏的展开与收缩实现原型的动态交互&#xff0c;主要使用区域是左边或者顶部的导航栏展开与收缩&#xff0c;同一级导航下的小…

Android 自定义SwitchPreference

1. 为SwitchPreference 添加背景&#xff1a;custom_preference_background.xml <?xml version"1.0" encoding"utf-8"?> <selector xmlns:android"http://schemas.android.com/apk/res/android"><item><shape android:s…

03-JAVA设计模式-组合模式

组合模式 什么是组合模式 组合模式&#xff08;Composite Pattern&#xff09;允许你将对象组合成树形结构以表示“部分-整体”的层次结构&#xff0c;使得客户端以统一的方式处理单个对象和对象的组合。组合模式让你可以将对象组合成树形结构&#xff0c;并且能像单独对象一…

python基础——类型注解【变量,函数,Union】

&#x1f4dd;前言&#xff1a; 上一篇文章Python基础——面相对象的三大特征提到&#xff0c;python中的多态&#xff0c;python中&#xff0c;类型是动态的&#xff0c;这意味着我们不需要在声明变量时指定其类型。然而&#xff0c;这可能导致运行时错误&#xff0c;因为我们…

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;需要启用…

Jmeter03:直连数据库

1 Jmete组件&#xff1a;直连数据库 1.1 是什么&#xff1f; 让Jmeter直接和数据库交互 1.2 为什么&#xff1f; 之前是通过接口操作数据库&#xff0c;可能出现的问题&#xff1a;比如查询可能有漏查误查的情况&#xff0c;解决方案是人工对不&#xff0c;效率低且有安全隐患…

Spring核心容器总结

2.2 核心容器总结 2.2.1 容器相关 BeanFactory是IoC容器的顶层接口&#xff0c;初始化BeanFactory对象时&#xff0c;加载的bean延迟加载 ApplicationContext接口是Spring容器的核心接口&#xff0c;初始化时bean立即加载 ApplicationContext接口提供基础的bean操作相关方法…

了解 Unity AI:从初学者到高级的综合指南

游戏中的AI是什么? 游戏中的人工智能是指利用人工智能技术使视频游戏中的非玩家角色和实体智能地行动、做出决策、对游戏环境做出反应,并提供引人入胜的动态游戏体验。什么是NPC? NPC 代表“非玩家角色”。NPC 是视频游戏、角色扮演游戏中不受人类玩家控制的角色。它们是计算…

Springboot+Vue项目-基于Java+MySQL的蜗牛兼职网系统(附源码+演示视频+LW)

大家好&#xff01;我是程序猿老A&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &…

Pytest精通指南(01)介绍与基本使用

文章目录 Pytest 简介Pytest 官网Pytest 核心Pytest 原理Pytest 用途Pytest 特点Pytest 安装Pytest 编写测试用例规则Pytest 编写第一条测试用例用例代码示例可执行测试执行一条测试执行多条测试 Pytest 运行方式run模式pytest模式run模式扩展命令行模式 Pytest.main()常用命令…

【Golang】并发编程之三大问题:原子性、有序性、可见性

目录 一、前言二、概念理解2.1 有序性2.2 原子性后果1&#xff1a;其它线程会读到中间态结果&#xff1a;后果2&#xff1a;修改结果被覆盖 2.3 可见性1&#xff09;store buffer(FIFO)引起的类似store-load乱序现象2&#xff09;store buffer(非FIFO)引起的类似store-store乱序…

太阳能智能语音卡口:环保与智能的完美结合/恒峰智慧科技

随着科技的飞速发展&#xff0c;我们的生活正在经历前所未有的变革。在这场变革中&#xff0c;太阳能智能语音卡口以其独特的魅力&#xff0c;成为环保与智能的完美结合&#xff0c;为我们的生活带来了更多的便捷和环保。 太阳能智能语音卡口&#xff0c;顾名思义&#xff0c;是…

React-hooks:useRef

useRef文档 useRef 是一个ReactHook&#xff0c;它能帮助引用一个不需要渲染的值。 const ref useRef(initialValue)参数 initialValue&#xff1a;ref对象的 current 属性的初始值&#xff0c;可以是任意类型的值&#xff0c;这个参数在首次渲染后被忽略。 返回值 useRe…

快速删除node_modules依赖包的命令rimraf

1、安装rimraf npm install -g rimraf 2、使用命令删除node_modules rimraf node_modules *** window系统&#xff0c;使用命令很快就删除node_modules ***

网工基础协议——TCP/UDP协议

TCP和UDP的不同点&#xff1a; TCP(Transmission Control Protocol&#xff0c;传输控制协议)&#xff1b; UDP(User Data Protocol&#xff0c;用户数据报协议)&#xff1b; TCP&#xff1a;传输控制协议&#xff0c;面向连接可靠的协议&#xff0c;只能适用于单播通信&…

Windows版MySQL5.7解压直用(免安装-绿色-项目打包直接使用)

windows下mysql分类 MySQL分为 安装版和解压版 安装版: 安装方便&#xff0c;下一步------下一步就OK了&#xff0c;但重装系统更换环境又要重新来一遍&#xff0c;会特别麻烦解压版&#xff08;推荐&#xff09;&#xff1a; 这种方式&#xff08;项目打包特别方便&#xf…

每日两题2

不同路径 class Solution { public:int uniquePaths(int m, int n) {vector<vector<int>> dp(m1, vector<int>(n1,0));//创建dp表dp[0][1] 1;//初始化//填表for(int i 1; i < m; i){for(int j 1; j < n; j){dp[i][j] dp[i-1][j] dp[i][j-1];}}ret…

第十五届蓝桥杯题解-好数

题目大意&#xff1a;一个数的低位为奇数&#xff0c;次低位为偶数&#xff0c;以此类推的数成为好数&#xff0c;例如&#xff1a;1&#xff0c;3&#xff0c;5&#xff0c;7&#xff0c;9 给定一个n&#xff0c;求1-n所有好数的个数&#xff0c;n<1e7 思路&#xff1a;一…