小白看了也会的Redux编程

news2024/11/28 6:51:33

目录

介绍

演示

异步action

react-redux

多组件管理的react-redux

扩展


介绍

redux是专门用于集中式管理状态的javascript库,并不是react的插件库。

比如你有多个组件A-E都想要用同一个组件D中的状态:
1)像以前我们可以通过父子组件通信的方式让父组件进行传递状态,或者是让兄弟组件之间通过订阅发布进行通信
2)当我们使用了redux就可以直接通过让redux进行统一的状态管理,谁想要用状态就自己去拿,省去了第一种方法的层层传递

 

redux三个核心概念

action

动作的对象

包含两个属性

      type: 标识属性 值为字符串 唯一 必要属性

      data: 数据属性 值类型任意 可选属性

reducer

用于初始化状态 加工状态

加工时 根据旧的state和action 产生新的state的纯函数

store

将state action reducer联系在一起的对象

该对象api

  (1) getState()得到state

  (2) dispatch(action): 分发action 触发reducer调用 产生新的state

  (3) subscribe(listener) 注册监听 当产生了新的state时 自动调用

演示

首先安装

npm i redux

准备项目结构

书写一个加减法案例

 

 创建reducer文件

 创建store

 

 调用时分配的type值要和reducer中定义的type类型一致

 注意这里的

store.subscribe订阅,这只是订阅了当前count单个组件 

 当使用了几十上百的组件让redux管理状态时,就需要在每个组件里都书写这个订阅,这样是很不方便的,所以可以直接在index.js主文件中直接书写一个全局订阅所有组件

 上面示例还可以进行细致拆分

新建一个action文件来进行简单管理action

新建action文件

使用action

 

还可以将type的值进行封装,这样可以避免因为疏忽造成单词拼错的错误,并且后期维护更改只需更改封装的一处地方即可

新建contant文件

 

 使用:

这样以后想要更改常量type的各种枚举值时只需更改contant文件即可 

异步action

在刚才的例子中书写异步加时是在count组件中定义一个异步任务去调用加 的方法的

并不是真正的异步action

redux需要中间件redux-thunk的配合才能定义异步aciton

安装中间件

npm i redux-thunk

 使用

store文件引入

 调用

react-redux

react官方还提供了一个react-redux的插件库用来对redux进行解耦,使得我们在使用组件时可以隔绝组件直接和redux进行交互,组件只需要通过父组件的props进行一系列的操作,而和redux的交互全部交给父组件来进行处理 具体原理图如下

 

安装react-redux

 npm i react-redux

 创建结构

 创建父子组件连接

 

子组件使用

 

可以看到子组件的引入中没有原先的store和action文件了,将store和action等进行了一系列的解耦

查看当前对象打印

 

 

 

其中容器组件中的mapStateToProps和mapDispatchToProps还可以进行一定程度的简写

第一步简写:

 第二步简写:

 第三步简写:

react-redux 的优化

之前在使用纯redux时,redux的状态改变时我们需要手动添加redux的状态订阅从而重新渲染组件

react-redux对这一功能进行了优化,我们只要使用了react-redux,它内部已经封装好了订阅功能,这里不需要我们再进行手动的订阅了

 

 测试页面还是正常的,这里不做页面测试的展示了

在App.js文件中引入了容器组件,如果这里的容器组件有几十上百个时候,我们就需要每个都手动添加store={store},react-redux对此点也进行了优化

 首先删除掉每个容器组件的store={store}

 在引入<App>组件的文件中引入react-redux的api: Provider

直接包裹使用,这样以后不管有多少容器组件,都不需要我们再一个一个手动添加store={store}了 

为了避免以后组件和容器组件过多,比如有10个组件的话,就需要再书写10个容器组件来对原组件进行包裹,这样产生的文件可能会冗余,其实可以直接将容器组件和组件进行合并为一个文件

下面给出一个合并例子


//引入connect用于连接UI组件与redux
import {connect} from 'react-redux'
import { createJiaAction, createJiaAsyncAction, createJianAction } from '../../redux/count_action'


import React, { Component } from 'react'
class Count extends Component {
    // componentDidMount(){
    //     //store订阅组件状态更新 每当状态值更新时就去重新渲染
    //     store.subscribe(()=>{
    //         this.setState({})
    //     })
    // }
      jia=()=>{
        //拿取当前下拉值
        const {value} = this.selectNumber
         //value*1 是将字符串类型数字转数字 也可写为value-0
        this.props.jia(value*1)
      }
  
      jian=()=>{
         //拿取当前下拉值
         const {value} = this.selectNumber
         //value*1 是将字符串类型数字转数字 也可写为value-0
        this.props.jian(value-0)
      }
  
      jiaIfOdd=()=>{
        const {value} = this.selectNumber
        if(this.props.count %2 ===1){
            this.props.jia(value-0)
        }
      }
  
      jiaAsync=()=>{
        const {value} = this.selectNumber
        // setTimeout(()=>{
            // store.dispatch(createJiaAsyncAction(value*1,1500))
        // },1000)
        this.props.asyjia(value-0,1000)
      }
      render(){
        console.log('当前对象')
        console.log(this)
          return (
            <div>
              <h1>当前求和值为: {this.props.count}</h1>
              <select ref={c => this.selectNumber = c}>
                  <option value='1'>1</option>
                  <option value='2'>2</option>
                  <option value='3'>3</option>
                  <option value='4'>4</option>
              </select>&nbsp;
              <button onClick={this.jia}>+</button>&nbsp;&nbsp;
              <button onClick={this.jian}>-</button>&nbsp;&nbsp;
              <button onClick={this.jiaIfOdd}>当前求和为奇数时加</button>&nbsp;&nbsp;
              <button onClick={this.jiaAsync}>异步任务加</button>&nbsp;&nbsp;
          </div>
          )
      }
    }



//mapStateToProps函数返回的对象中的key作为传递给UI组件的key
//value作为出传递给UI组件的pros的value-状态值
// function mapStateToProps(state){
//     return {count:state}
// }
//简写
// const mapStateToProps = state => ({count:state})

// mapDispatchToProps函数返回的对象结构为: {key:function}
//对象中的key作为传递给ui组件props的key
//value作为传递给ui组件props的value-操作状态的方法
// function mapDispatchToProps(dispatch){
//     return {
//         jia:number =>dispatch(createJiaAction(number)),
//         //上一行写法等价于
//         jian: (number)=>{return dispatch(createJianAction(number))},
//         asyjia: (number,time)=>dispatch(createJiaAsyncAction(number,time))
//     }
// }

// 简写
// const mapDispatchToProps = (dispatch)=>({
//     jia:number =>dispatch(createJiaAction(number)),
//     //上一行写法等价于
//     jian: (number)=>{return dispatch(createJianAction(number))},
//     asyjia: (number,time)=>dispatch(createJiaAsyncAction(number,time))
// })

//使用connect()()创建并暴露一个Count的容器组件
// export default connect(state => ({count:state}),(dispatch)=>({
//     jia:number =>dispatch(createJiaAction(number)),
//     //上一行写法等价于
//     jian: (number)=>{return dispatch(createJianAction(number))},
//     asyjia: (number,time)=>dispatch(createJiaAsyncAction(number,time))
// }))(CountUi)

export default connect(state => ({count:state}),
  {
    jia:createJiaAction,
    jian:createJianAction,
    asyjia:createJiaAsyncAction
  }
)(Count)

 直接将组件书写在容器组件中,但是组件不再进行暴露了,而容器组件也不需要再去引入组件了

多组件管理的react-redux

前面的例子是单个容器组件的react-redux管理,如果是多个组件需要使用react-redux进行数据共享呢

下面再新建一个person组件来进行演示,并新建属于person的action和reducer

将各属于count,person的action, reducer再次进行结构的细分

 添加新的常量

  编写person的action

 编写person的reducer

此时之前书写的store需要一些调整,之前只有count组件时,store文件里只引入了count组件的reducer进行服务,而这里新加了Person组件,所以store文件中需要再引入person组件的reducer进行对Person组件服务

 

 书写Person组件

这里采用容器组件和组件合并的形式


//引入connect用于连接UI组件与redux
import {connect} from 'react-redux'
//引入迷你版uid生成器
import {nanoid} from 'nanoid'
import { addObj } from '../../redux/actions/person/action'
import React, { Component } from 'react'

class Person extends Component {
      addObj = ()=>{
        let uName = this.uName.value
        let uAge = this.uAge.value
        let perObj = {id:nanoid(),uName,uAge}
        this.uName.value = ''
        this.uAge.value = ''
        this.props.jiaPer(perObj)
      }
      render(){
        console.log('person组件的this')
        console.log(this.props)
          return (
            <div>
              <h1>Person组件</h1>
              <h2>求和结果为{this.props.resultHe}</h2>
              <input ref={c => this.uName = c} placeholder='请输入名字'/>
              <input ref={c => this.uAge = c} placeholder='请输入年龄'/>
              <button onClick={this.addObj}>点击添加</button>
              <ul>
                {
                  this.props.perObjs.map(item=>{
                    return (
                      <li key={item.id}>名字---{item.uName},年龄--{item.uAge}</li>
                    )
                  })
                }
              </ul>
          </div>
          )
      }
    }
export default connect(state => ({perObjs:state.pers,resultHe:state.he}),
  {
    jiaPer: addObj //映射 action中的person
  }
)(Person)

这个地方有些绕,要深入的理解下store的使用方法

countReducer和PeronReducer中的方法返回的最终数据都会被绑定在store的state中,而在store中又封装了一个总的reducer对象来将两个文件返回的数据作为value绑定在了

{

  he:countReducer,

  pers:personReducer

}

所以取值时就是直接state(相当于直接调用store.getState()方法).he或者state.pers了

 在person组件中取得count组件的求和值

 在count组件中取得person组件的人数值从而实现两个组件互相取得对方的数据实现数据共享

测试 

测试可以看到count组件拿取到了person组件的人数,person组件也拿到了count组件的求和数,从而两个组件借助react-redux实现了数据共享 

安装redux开发者工具

在谷歌开发者商店里搜索redux devtools下载插件进行安装

或者直接在下面链接中下载安装

链接:react全家桶资料
 

在浏览器插件安装中选择该文件夹即可

 该插件需要在react项目中配合第三方库进行使用

安装第三方库

npm i redux-devtools-extension

 

 

 重启项目

 可以看到该插件图表亮了,点击后唤出操作页面,该插件可以对redux中的state的变化进行可视化的监听,具体操作这里不再演示

扩展

纯函数

(1) 一类特别的函数: 只要是同样的输入(实参) 必定得到同样的输出(返回)

(2) 必须遵以下约束:

     1) 不得改写参数数据

     2) 不会产生任何副作用 例如网络请求 输入和输出设备

     3) 不能调用Date.now()或者Math.random()等不纯的方法

(3) redux的reducer函数必须是一个纯函数

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

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

相关文章

前几天面了个30岁左右的测试员,年薪50w问题基本都能回答上,必是刷了不少八股文···

互联网行业竞争是一年比一年严峻&#xff0c;作为测试工程师的我们唯有不停地学习&#xff0c;不断的提升自己才能保证自己的核心竞争力从而拿到更好的薪水&#xff0c;进入心仪的企业&#xff08;阿里、字节、美团、腾讯等大厂.....&#xff09; 所以&#xff0c;大家就迎来了…

TCP三次握手四次挥手(幽默版)

三次握手&#xff1a; 假设你是一只鸟&#xff0c;你要与另一只鸟进行交流。&#xff08;你是客户端&#xff09; 1.首先你会问候&#xff1a;“你好&#xff0c;我是一只鸟&#xff0c;你可以听到我说话吗&#xff1f;”&#xff08;一次会话&#xff09; 2.另一只鸟回答&am…

一文带你了解MySQL之Explain执行计划

前言&#xff1a; 一条查询语句在经过MySQL查询优化器的各种基于成本和规则的优化会后生成一个所谓的执行计划&#xff0c;这个执行计划展示了接下来具体执行查询的方式&#xff0c;比如多表连接的顺序是什么&#xff0c;对于每个表采用什么访问方法来具体执行查询等等。MySQL…

MySQL---show profile分析SQL、trace分析优化器执行计划

1. show profile分析SQL Mysql从5.0.37版本开始增加了对 show profiles 和 show profile 语句的支持。show profiles 能够 在做SQL优化时帮助我们了解时间都耗费到哪里去了。 通过 have_profiling 参数&#xff0c;能够看到当前MySQL是否支持profile&#xff1a; select ha…

3年软件测试经验月薪7k,只会“点点点”,我该如何破局?

经常听到一些行业内的朋友说 “做测试&#xff0c;有手就行” 但事实真的是如此嘛&#xff1f; 随着测试行业的发展&#xff0c;越来越多的测试岗位对自动化测试&#xff0c;性能测试都有所要求&#xff0c;这对于很多只会功能测试的职场老人们来说&#xff0c;有了一丝丝的危…

Druid连接池技术实践

什么是Druid连接池&#xff1f; Druid连接池是阿里巴巴开源的数据库连接池项目。 Druid连接池为监控而生&#xff0c;内置强大的监控功能&#xff0c;监控特性不影响性能。功能强大&#xff0c;能防SQL注入&#xff0c;内置Loging能诊断Hack应用行为。 哦&#xff0c;首先Dru…

2023ACP世界大赛教育者论坛:让职业教育直面AI机遇与挑战

“AI技术的普及对创意行业和教育带来的影响和变革-2023 Adobe Certified Professional教育者论坛”在苏州西交利物浦大学成功举办。 本次论坛&#xff0c;由Adobe Certified Professional 世界大赛中国赛区组委会主办&#xff0c;联动了来自院校、海内外杰出的创意公司及国际知…

搭建飞书早报机器人

飞书是字节跳动推出的一款企业级通讯及协作平台&#xff0c;于2016年正式上线。它是一款基于云计算技术的软件工具&#xff0c;可以帮助企业实现快速高效的沟通和协作&#xff0c;提升工作效率&#xff0c;降低沟通成本。下面将详细介绍飞书的功能、特点以及使用体验。 功能介…

Android动画深入分析(View动画)

Android动画深入分析(View动画) Android的动画我其实在View的滑动里面写过,主要还是分为2点。 一个就是View动画&#xff0c;还有一个是属性动画 先讲述View动画 View动画 View动画主要分为4种,平移动画,缩放动画,旋转动画,透明度动画。 还有一个叫帧动画,但是表现方式和…

python+vue旅游攻略分享推荐网站p0667

基于Python语言设计并实现了旅游分享网站。该系统基于B/S即所谓浏览器/服务器模式&#xff0c;应用Django框架&#xff0c;选择MySQL作为后台数据库。系统主要包括用户、景点信息、攻略分类、旅游攻略、门票购买、留言反馈、论坛管理、系统管理等功能模块。 软件开发前的需求分…

某渣渣企业平台相关加密参数

网址 aHR0cHM6Ly93d3cucWNjLmNvbS93ZWIvZWxpYi90ZWNsaXN0P3RlYz1UX1RTTUVT抓包 GET /api/elib/getTecList?countyCode110101&flag&industry&isSortAsc&pageIndex2&pageSize20&provinceBJ&registCapiBegin&registCapiEnd&searchKey&…

修改git已经push到远端的最近一次提交的commit

需求&#xff1a; 最新一次提交的message写错了且已经push到远程仓库&#xff0c;但是又不想重新创建一个commit记录。 注意&#xff1a; 如果是多人协同开发&#xff0c;使用强推前一定确保当前版本最新&#xff0c;期间无人提交代码。 使用git Bash进入命令行窗口 git co…

基于langChain 的privateGPT 文档问答 研究

参考&#xff1a;gihtub代码 https://github.com/imartinez/privateGPT 官网 privateGPT可以在断网的情况下&#xff0c;借助GPT和文档进行交互&#xff0c;有利于保护数据隐私。 privateGPT可以有四个用处&#xff1a; 1.增强知识管理&#xff1a;私有LLMs自动化&#xff0c…

《Spring Guides系列学习》guide26 - guide30

要想全面快速学习Spring的内容&#xff0c;最好的方法肯定是先去Spring官网去查阅文档&#xff0c;在Spring官网中找到了适合新手了解的官网Guides&#xff0c;一共68篇&#xff0c;打算全部过一遍&#xff0c;能尽量全面的了解Spring框架的每个特性和功能。 接着上篇看过的gu…

numpy库报错has no attribute ‘_no_nep50_warning‘的解决

本文介绍在Python中&#xff0c;numpy库出现报错module numpy has no attribute _no_nep50_warning的解决方法。 一次&#xff0c;在运行一个Python代码时&#xff0c;发现出现报错module numpy has no attribute _no_nep50_warning&#xff0c;如下图所示。 其中&#xff0c;这…

华为nova11系列:一个月的深度体验感受,告诉你值不值得入手

作为一个追求时尚风格的年轻人&#xff0c; nova系列手机一直是我的关注重点。nova 11 Pro发布之后&#xff0c;独特少见的11号色一下子就戳中了我&#xff0c;于是第一时间我给我自己和我老婆分别下单了一台nova 11和nova 11 Pro。 作为主力机深度使用一个月后&#xff0c;可以…

如何做好建筑行业的信息化建设?

如何做好建筑行业的信息化建设&#xff1f; 首先&#xff0c;我们来了解一下&#xff0c;什么是信息化转型&#xff1f; 信息化转型是指企业或组织通过应用信息技术&#xff0c;以提高业务效率和创新能力&#xff0c;实现组织战略目标的过程。 随着数字技术的发展&#xff0…

把字节大佬花3个月时间整理的软件测试面经偷偷给室友,差点被他开除了···

写在前面 “这份软件测试面经看起来不错&#xff0c;等会一起发给他吧”&#xff0c;我看着面前的面试笔记自言自语道。 就在这时&#xff0c;背后传来了leder“阴森森”的声音&#xff1a;“不错吧&#xff0c;我可是足足花了三个月整理的” 始末 刚入职字节的我收到了大学室…

Junit常见用法

一.Junit的含义 Junit是一种Java编程语言的单元测试框架。它提供了一些用于编写和运行测试的注释和断言方法&#xff0c;并且可以方便地执行测试并生成测试报告。Junit是开源的&#xff0c;也是广泛使用的单元测试框架之一。 二.Junit常用注解 1.Test 表示执行此测试用例 T…

代码随想录训练营Day51| 300.最长递增子序列 674. 最长连续递增序列 718. 最长重复子数组

目录 学习目标 学习内容 300.最长递增子序列 674. 最长连续递增序列 718. 最长重复子数组 学习目标 300.最长递增子序列 674. 最长连续递增序列 718. 最长重复子数组 学习内容 300.最长递增子序列 300. 最长递增子序列 - 力扣&#xff08;LeetCode&#xff09;https…