redux的介绍、安装、三大核心与执行流程

news2024/11/16 15:58:33

redux的介绍、安装、三大核心与执行流程

  • 一、redux的基本介绍
  • 二、redux的安装
  • 三、redux核心概念
    • 3.1 action
    • 3.2 reducer
    • 3.3 store
  • 四、Redux代码执行流程
  • 五、加减案例练习

一、redux的基本介绍

  • redux中文官网
  • Redux 是 React 中最常用的状态管理工具(状态容器)
  • React 只是 DOM 的一个抽象层(UI 库),并不是 Web 应用的完整解决方案。因此 React 在涉及到数据的处理以及组件之间的通信时会比较复杂

不使用redux 与 使用redux的区别 (组件之间的通讯问题)

在这里插入图片描述

  • 不使用redux
    • 1.只能使用父子组件通讯、状态提升等 React 自带机制
    • 2.处理远房亲戚(非父子)关系的组件通讯时乏力
    • 3.组件之间的数据流混乱,出现 Bug 时难定位
  • 使用redux
    • 1.集中式存储和管理应用的状态
    • 2.处理组件通讯问题时,无视组件之间的层级关系
    • 3.简化大型复杂应用中组件之间的通讯问题
    • 4.数据流清晰,易于定位 Bug

二、redux的安装

npm i redux

三、redux核心概念

  • 为了让代码各部分职责清晰、明确,Redux 代码被分为三个核心概念:action/reducer/store
    • action -> reducer -> store
    • action(动作):描述要做的事情
    • reducer(函数):更新状态
    • store(仓库):整合 action 和 reducer

类比生活中的例子来理解三个核心概念:

  • 1.action:相当于公司中要做的事情,比如软件开发、测试,打扫卫生等
  • 2.reducer:相当于公司的员工,负责干活的
  • 3.store:相当于公司的老板
  • 4.流程:老板(store)分配公司中要做的事情(action)给员工(reducer),员工干完活把结果交给老板

3.1 action

  • action:描述要做的事情,项目中的每一个功能都是一个 action
    • 计数器案例:计数器加1、减1
    • 购物车案例:获取购物车数据、切换商品选中状态
    • 项目:登录,退出等
  • 特点
    • 只描述做什么
    • JS 对象,必须带有 type 属性,用于区分动作的类型
    • 根据功能的不同,可以携带额外的数据(比如,payload 有效载荷,也就是附带的额外的数据),配合该数据来完成相应功能

核心代码 (原生html中使用)

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <!-- 引入redux -->
    <script src="./node_modules/redux/dist/redux.js"></script>
  </head>
  <body>
    <div>1</div>
    <button>+1</button>
    <button>-1</button>
  </body>
  <script>
    //1.action 是一个函数  必须有type属性

    //1.1原始创建
    // const action={
    //     type:'ADD'
    // }
    
    //1.2 动态action 函数创建
    // const Add = () => {
    //   return {
    //     type: 'ADD',
    //   }
    // }

    //简写 并传参  使用()包裹对象
    const Add = (id) => ({ type: 'ADD', id })
    console.log('action', Add(3))
  </script>
</html>

3.2 reducer

  • reducer:函数,用来处理 action 并更新状态,是 Redux 状态更新的地方
  • 特点
    • 函数签名为:(prevState, action) => newState
    • 接收上一次的状态和 action 作为参数,根据 action 的类型,执行不同操作,最终返回新的状态
    • 注意:该函数一定要有返回值,即使状态没有改变也要返回上一次的状态
    • 约定:reducer 是一个纯函数,并且不能包含 side effect 副作用(比如,不能修改函数参数、不能修改函数外部数据、不能进行异步操作等)
    • 纯函数:相同的输入总是得到相同的输出
    • 1.不要直接修改参数 state 的值(也就是:不要直接修改当前状态,而是根据当前状态值创建新的状态值)
    • 2.不要使用 Math.random() / new Date() / Date.now() / ajax 请求等不纯的操作
    • 3.不要让 reducer 执行副作用(side effect)

核心代码 (原生html中使用)

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <!-- 引入redux -->
    <script src="./node_modules/redux/dist/redux.js"></script>
  </head>
  <body>
    <div>1</div>
    <button>+1</button>
    <button>-1</button>
  </body>
  <script>
    //reducer 接收两个参数   必须有返回值   必须是纯函数
    //参数1 上一次的状态
    //参数2 action

    //累加
    const Add = (num) => ({ type: 'ADD', num })

    //类减
    const Sub = (num) => ({ type: 'SUB', num })

    //reducer
    // const reducer = (state, action) => {
    //   return 'reducer返回'
    // }

    const reducer = (state = 0, action) => {
      //使用switch case
      switch (action.type) {
        case 'ADD':
          return state + 1
        case 'SUB':
          return state - 1
        default:
          return state
      }
    }
    console.log('减法', reducer(1, Sub()))
    console.log('加法', reducer(1, { type: 'ADD' }))
  </script>
</html>

3.3 store

  • store:仓库,Redux 的核心,整合 action 和 reducer
  • 特点
    • 一个应用只有一个 store
    • 维护应用的状态,获取状态:store.getState()
    • 发起状态更新时,需要分发 action:store.dispatch(action)
    • 创建 store 时接收 reducer 作为参数:const store = createStore(reducer)
    • 订阅(监听)状态变化:const unSubscribe = store.subscribe(() => {})
    • 取消订阅状态变化: unSubscribe()

核心代码 (原生html中使用)

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <!-- 引入redux -->
    <script src="./node_modules/redux/dist/redux.js"></script>
  </head>
  <body>
    <div>1</div>
    <button>+1</button>
    <button>-1</button>
  </body>
  <script>
    //累加
    const Add = (num) => ({ type: 'ADD', num })

    //类减
    const Sub = (num) => ({ type: 'SUB', num })

    function reducer(state = 100, action) {
      //使用switch case
      switch (action.type) {
        case 'ADD':
          return state + 1
        case 'SUB':
          return state - 1
        default:
          return state
      }
    }
    //因为不是es6 引入  全局有一个window.Redux
    console.log('window.Redux', window.Redux)

    //解构 createStore
    const { createStore } = window.Redux
    console.log('createStore', createStore)

    //创建store 参数一必传 (reducer)
    const store = createStore(reducer)

    console.log('store', store)
    //dispatch getState subscribe

    //1.获取redux中的数据
    store.getState()
    console.log('store.getState', store.getState())

    //2.订阅:只要state发生变化 这个订阅的回调函数 就会执行
    store.subscribe(() => {
      console.log('订阅', store.getState())
    })

    //3.发起状态更新时,需要分发 action
    store.dispatch(Add())
    console.log('store.getState', store.getState())
    store.dispatch(Sub())
    console.log('store.getState', store.getState())
  </script>
</html>

四、Redux代码执行流程

  • 1.创建 store 时,Redux 就会先调用一次 reducer,来获取到默认状态
  • 2.分发动作 store.dispatch(action)更新状态
  • 3.Redux store 调用 reducer 传入:上一次的状态(当前示例中就是:10)和 action({ type: 'increment' }),计算出新的状态并返回
  • 4.reducer 执行完毕后,将最新的状态交给 store,store 用最新的状态替换旧状态,状态更新完毕
import { createStore } from 'redux'
const store = createStore(reducer)

// reducer(10, { type: 'increment' })
function reducer(state = 10, action) {
  console.log('reducer:', state, action)
  switch (action.type) {
    case 'increment':
      return state + 1
    default:
      return state
  }
}

console.log('状态值为:', store.getState()) // 10

// 发起更新状态:
// 参数: action 对象
store.dispatch({ type: 'increment' })
// 相当于: reducer(10, { type: 'increment' })

console.log('更新后:', store.getState()) // 11

五、加减案例练习

  • 准备两个按钮 点击加号按钮 数值+1 点击减号按钮 数值-1
    在这里插入图片描述

实现代码

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <!-- 引入redux -->
    <script src="./node_modules/redux/dist/redux.js"></script>
  </head>
  <body>
    <div>1</div>
    <button class="add">+1</button>
    <button class="sub">-1</button>
  </body>
  <script>
    //第一步 创建action
    //加法
    const Add = (num) => ({ type: 'ADD', num })
    //减法
    const Sub = (num) => ({ type: 'SUB', num })

    //第二步 创建 reducer
    const reducer = (state = 100, action) => {
      switch (action.type) {
        case 'ADD':
          return state + 1
        case 'SUB':
          return state - 1
        default:
          return state
      }
    }

    //第三步 引入store
    //3.1 解构出store 并传递reducer
    const { createStore } = window.Redux
    const store = createStore(reducer)

    //3.2 store.getState获取redux中的数据 初始原始值
    document.querySelector('div').innerHTML = store.getState()

    //3.3 store.subscribe 订阅获取state变化
    store.subscribe(() => {
      console.log('值发生变化', store.getState())
      document.querySelector('div').innerHTML = store.getState()
    })

    //3.4 绑定点击事件 并调用store.dispatch 分发action
    document.querySelector('.add').onclick = function () {
      store.dispatch(Add())
    }
    document.querySelector('.sub').onclick = function () {
      store.dispatch(Sub())
    }
  </script>
</html>

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

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

相关文章

B树和B+树MySQL为什么用B+树?

文章目录 B树和B树B树B树的定义B树的插入操作删除操作 B树B树的定义B树的插入操作删除操作 B树和B树的区别?MySQL数据库为啥用B树作为索引&#xff0c;而不用B树? B树和B树 原文链接&#xff1a;https://blog.csdn.net/jinking01/article/details/115130286 B树 B树的定义…

深入理解python虚拟机:程序执行的载体——栈帧

栈帧&#xff08;Stack Frame&#xff09;是 Python 虚拟机中程序执行的载体之一&#xff0c;也是 Python 中的一种执行上下文。每当 Python 执行一个函数或方法时&#xff0c;都会创建一个栈帧来表示当前的函数调用&#xff0c;并将其压入一个称为调用栈&#xff08;Call Stac…

RT1052的EPWM

文章目录 1 EPWM介绍1.1 引脚1.2 时钟1.3 比较寄存器 2 函数 1 EPWM介绍 RT1052 具有 4 个 eFlexPWM(eFlexWM1~eFlex_PWM4)。 每个 eFlexPWM 可以产生四路互补 PWM即产生 8 个 PWM&#xff0c;也可以产生相互独立的 PWM 波。四路分别是模块0-3每个 eFlexPWM 具有各自的故障检…

如何学习专业的学术用语01

问题的提出——凭啥人家写的词汇这么专业 做法一 做法二&#xff1a;做一个专业数据库 专门做教育技术类的

换过3个工作,我却得出10年测试人的血泪经验

我跟大多数IT职场的测试新人起点差不多&#xff0c;在测试的这条路上&#xff0c;没有天生的聪明天资&#xff0c;也没有一个耀眼的学历。在北京这样一个随便一个同事不是清华的本硕&#xff0c;就是北邮北航的硕士下&#xff0c;自己也常常感到惭愧。 自己从事测试多年&#…

论文笔记 Graph Attention Networks

2018 ICLR 1 intro 1.1. GCN的不足 无法完成inductive任务 inductive任务是指&#xff1a; 训练阶段与测试阶段需要处理的graph不同。通常是训练阶段只是在子图上进行&#xff0c;测试阶段需要处理未知的顶点。GGN 的参数依赖于邻接矩阵A/拉普拉斯矩阵L&#xff0c;所以换了…

一个完整挖洞 /src 漏洞实战流程【渗透测试】

目录: 1.如何找漏洞 2.找到后如何挖漏洞 3.漏洞如何提交 只要搞渗透&#xff0c;不就会听到很多行业内人前辈一直在重复:“信息搜集” 信息搜集有多重要&#xff0c;你搜集的到的多少资产信息&#xff0c;决定了你后续进行的一系列实战到什么程度! 要说 SQL 注入的漏洞咋找…

【博客700】如何使用 Nginx Ingress 快速实现金丝雀与蓝绿部署

如何使用 Nginx Ingress 快速实现金丝雀与蓝绿部署 背景 越来越多的应用采用微服务架构&#xff0c;应用数量相比传统模式更多&#xff0c;管理更加复杂&#xff0c;发布更加频繁&#xff0c;如果直接将新版本上线发布给全部用户。一旦遇到线上事故&#xff08;或BUG&#xff…

Selenium的使用:WEB功能测试

Selenium是ThrougthWorks公司一个强大的开源WEB功能测试工具系列&#xff0c;本系统包括多款软件 Selenium语言简单&#xff0c;用(Command,target,value)三种元素组成一个行为&#xff0c;并且有协助录制脚本工具&#xff0c;但Selenese有一些严格的限制&#xff1a; …

在字节和滴滴划水四年,过于真实了...

先简单交代一下&#xff0c;我是某不知名211的计算机本硕&#xff0c;18年毕业加入滴滴&#xff0c;之后跳槽到了头条&#xff0c;一直从事测试开发相关的工作。之前没有实习经历&#xff0c;算是四年半的工作经验吧。 这四年半之间完成了一次晋升&#xff0c;换了一家公司&am…

torch.cuda.is_available()为false的解决办法

一、问题 在进行torch进行开发的过程中&#xff0c;我们习惯性的会使用pip install torch这样的方式来安装torch的包。 其实这样的是安装CPU的torch。 在导入包&#xff0c;执行下面代码的过程中&#xff0c;会出现结果为false。 import torchprint(torch.cuda.is_availabl…

04-数据集汇总

一、3D检测数据集 1、Argoverse数据集[参考] 年份&#xff1a;2019年&#xff1b; 作者&#xff1a;Argo AI等&#xff1b; 场景数&#xff1a;共113个场景&#xff0c;室外&#xff0c;包括USA&#xff0c;Pennsylvania&#xff0c;Miami&#xff0c;Florida等&#xff1b…

Django进阶:DRF(Django REST framework)

什么是DRF&#xff1f; DRF即Django REST framework的缩写&#xff0c;官网上说&#xff1a;Django REST framework是一个强大而灵活的工具包&#xff0c;用于构建Web API。 简单来说&#xff1a;通过DRF创建API后&#xff0c;就可以通过HTTP请求来获取、创建、更新或删除数据(…

CFDEM-OpenFOAM-Yade安装教程

在网上搜索与OpenFOAM相关的颗粒两相流计算资料时&#xff0c;发现了一个CFD-DEM coupled simulations with Yade and OpenFOAM。 在此之前&#xff0c;我学习过OpenFOAM自带的颗粒计算求解器&#xff0c;但是自带的求解器有很多缺点&#xff0c;最大的缺点就是颗粒运动方程的求…

10. 实现业务功能--退出登录

目录 1. 实现 Controller 2. 单体测试 3. 实现前端界面 退出的具体实现逻辑如下&#xff1a; 1. 用户访问退出接口 2. 服务器注销 Session( 在 Controller 中可以直接进行处理 &#xff09; 3. 返回成功或失败 4. 如果返回成功浏览器跳转到相应页面 5. 结束 一般来说&#…

Python入门--开发工具

Python是一种优秀的编程语言&#xff0c;具有简单易学、开放源代码、高效可靠等特点&#xff0c;广泛应用于Web开发、科学计算、数据分析、人工智能等领域。以下是常用的Python开发工具&#xff1a; PyCharm&#xff1a;JetBrains公司开发的Python IDE&#xff0c;功能强大&…

VMware vSphere Client端设置热添加虚拟机的CPU和内存

使用vSphere Client连接到VMware ESXi Server&#xff0c;在“配置→网络”中&#xff0c;可以看到&#xff0c;当前有两个虚拟交换机&#xff0c;并且为该虚拟交换机分配了管理地址10.10.228.81&#xff0c;点击“添加网络”如图所示。 添加配置向导&#xff0c;在网络类型&am…

AIGC的变革

AIGC&#xff08;Artificial Intelligence and General Computing&#xff09;是一个涵盖人工智能和通用计算的领域&#xff0c;它的发展前景非常广阔。以下是一些关于AIGC发展前景的观点&#xff1a; 人工智能市场增长迅速&#xff1a;随着人工智能技术的迅猛发展&#xff0c;…

嵌入式学习之投票系统改进版本

今天周六&#xff0c;9点钟就开始写代码&#xff0c;但是呢&#xff0c;一直在家里面&#xff0c;真的很容易心烦气躁&#xff0c;我正在研究有没有什么方法可以改变我的状态&#xff0c;今天写的代码是做昨天做的选票系统的改进&#xff0c;代码如下&#xff1a;

C语言实现贷款计算器

等额本金&#xff0c;等额本息数学推导:贷款 买房&#xff0c;利息怎么算&#xff1f;不要被忽悠了&#xff01;李永乐老师讲等额本金和等额本息 一个心血来潮的研究&#xff0c;避免以后买房被坑。 捣鼓了半天才发现原来支付宝的那个利率是年利率不是月利率&#xff0c;坑了…