React(react18)中组件通信04——redux入门

news2024/9/27 19:19:50

React(react18)中组件通信04——redux入门

  • 1. 前言
    • 1.1 React中组件通信的其他方式
    • 1.2 介绍redux
      • 1.2.1 参考官网
      • 1.2.2 redux原理图
      • 1.2.3 redux基础介绍
        • 1.2.3.1 action
        • 1.2.3.2 store
        • 1.2.3.3 reducer
    • 1.3 安装redux
  • 2. redux入门例子
  • 3. redux入门例子——优化(reducer 和 store拆开)
    • 3.1 想要实现的效果
    • 3.2 代码设计
    • 3.3 添加 重新渲染
    • 3.4 附代码

1. 前言

1.1 React中组件通信的其他方式

  • React中组件通信01——props.
  • React中组件通信02——消息订阅与发布、取消订阅以及卸载组件时取消订阅.
  • React(react18)中组件通信03——简单使用 Context 深层传递参数.

1.2 介绍redux

1.2.1 参考官网

  • 讲解、例子,参考官网,官网地址如下:
    Redux 中文文档——https://www.redux.org.cn/.

1.2.2 redux原理图

  • 原理图,如下:
    在这里插入图片描述
  • 简单解释
    • 要想更新 state 中的数据,你需要发起一个 actionAction 就是一个普通 JavaScript 对象(注意到没,这儿没有任何魔法?)用来描述发生了什么。
    • 强制使用 action 来描述所有变化带来的好处是可以清晰地知道应用中到底发生了什么。如果一些东西改变了,就可以知道为什么变。action 就像是描述发生了什么的指示器。
    • 最终,为了把 action 和 state 串起来,开发一些函数,这就是 reducer。再次地强调,没有任何魔法,reducer 只是一个接收 state 和 action,并返回新的 state 的函数,并且是一个纯函数
    • 而整个应用的 state 被储存在一棵 object tree 中,并且这个 object tree 只存在于唯一一个 store 中。

1.2.3 redux基础介绍

1.2.3.1 action
  • Action 是把数据从应用(这里之所以不叫 view 是因为这些数据有可能是服务器响应,用户输入或其它非 view 的数据 )传到 store 的有效载荷。它是 store 数据的唯一来源。一般来说你会通过 store.dispatch() 将 action 传到 store。
  • Action 本质上是 JavaScript 普通对象。我们约定,action 内必须使用一个字符串类型的 type 字段来表示将要执行的动作。多数情况下,type 会被定义成字符串常量。当应用规模越来越大时,建议使用单独的模块或文件来存放 action。
1.2.3.2 store
  • Store 就是把它们联系到一起的对象。Store 有以下职责:
    • 维持应用的 state;
    • 提供 getState() 方法获取 state;
    • 提供 dispatch(action) 方法更新 state;
    • 通过 subscribe(listener) 注册监听器;
    • 通过 subscribe(listener) 返回的函数注销监听器。
  • 强调一下 Redux 应用只有一个单一的 store。当需要拆分数据处理逻辑时,你应该使用 reducer 组合 而不是创建多个 store。
1.2.3.3 reducer
  • Reducers 指定了应用状态的变化如何响应 actions 并发送到 store 的,记住 actions 只是描述了有事情发生了这一事实,并没有描述应用如何更新 state。
  • reducer 就是一个纯函数,接收旧的 state 和 action,返回新的 state。
  • 整个应用只有一个单一的 reducer 函数:这个函数是传给 createStore 的第一个参数。一个单一的 reducer 最终需要做以下几件事:
    • reducer 第一次被调用的时候,state 的值是 undefined。reducer 需要在 action 传入之前提供一个默认的 state 来处理这种情况。
    • reducer 需要先前的 state 和 dispatch 的 action 来决定需要做什么事。
    • 假设需要更改数据,应该用更新后的数据创建新的对象或数组并返回它们。
    • 如果没有什么更改,应该返回当前存在的 state 本身。

1.3 安装redux

  • 命令如下:
    npm install --save redux
    

2. redux入门例子

  • 直接从官网拷贝的例子,例子地址:
    https://www.redux.org.cn/.
  • 例子如下:
    在这里插入图片描述
    import { createStore } from 'redux';
    
    /**
     * 这是一个 reducer,形式为 (state, action) => state 的纯函数。
     * 描述了 action 如何把 state 转变成下一个 state。
     *
     * state 的形式取决于你,可以是基本类型、数组、对象、
     * 甚至是 Immutable.js 生成的数据结构。惟一的要点是
     * 当 state 变化时需要返回全新的对象,而不是修改传入的参数。
     *
     * 下面例子使用 `switch` 语句和字符串来做判断,但你可以写帮助类(helper)
     * 根据不同的约定(如方法映射)来判断,只要适用你的项目即可。
     */
    function counter(state = 0, action) {
      switch (action.type) {
      case 'INCREMENT':
        return state + 1;
      case 'DECREMENT':
        return state - 1;
      default:
        return state;
      }
    }
    
    // 创建 Redux store 来存放应用的状态。
    // API 是 { subscribe, dispatch, getState }。
    let store = createStore(counter);
    
    // 可以手动订阅更新,也可以事件绑定到视图层。
    store.subscribe(() =>
      console.log(store.getState())
    );
    
    // 改变内部 state 惟一方法是 dispatch 一个 action。
    // action 可以被序列化,用日记记录和储存下来,后期还可以以回放的方式执行
    store.dispatch({ type: 'INCREMENT' });// 1
    store.dispatch({ type: 'INCREMENT' });// 2
    store.dispatch({ type: 'DECREMENT' });// 1
    
  • 效果如下:
    在这里插入图片描述

3. redux入门例子——优化(reducer 和 store拆开)

3.1 想要实现的效果

  • 因为上面的简单例子中的state没有在页面上渲染,所以简单优化一下,实现页面渲染操作,想呈现的效果如下:
    在这里插入图片描述

  • 如果用纯react写的话,很简单,代码如下:

    import { useState } from "react";
    
    function CountNum(){
        const [count,setCount] = useState(0);
    
        function add(){
            setCount(count => count+1);
        }
    
        function subtract(){
            setCount(count => count-1);
        }
    
        return(
            <div>
                当前数字是:{count}
                <br /><br />
    
                <button onClick={add}>点我 +1</button> <br /><br />
                <button onClick={subtract}>点我 -1</button>
            </div>
        )
    }
    export default CountNum;
    
  • 但我们目的是用redux实现,所以继续……

3.2 代码设计

  • 项目结构,如下:
    在这里插入图片描述
  • store.js 和 countReducer.js 如下:
    在这里插入图片描述
  • CountNumRedux.jsx 组件如下:
    在这里插入图片描述
  • 看效果,有问题
    在这里插入图片描述
    怎么重新渲染?继续……

3.3 添加 重新渲染

  • 使用 useEffect 进行重新渲染,核心代码如下:

    useEffect(()=>{
        store.subscribe(()=>{
            console.log('订阅更新,打印2-----',store.getState());
            setCount(store.getState());
        });
    });
    

    在这里插入图片描述

  • 然后再看效果:
    在这里插入图片描述

  • 关于useEffect ,可以看下面的文章:
    React中组件通信02——消息订阅与发布、取消订阅以及卸载组件时取消订阅.

3.4 附代码

  • countReducer.js

    /**
     * 这是一个 reducer,形式为 (state, action) => state 的纯函数。
     * 描述了 action 如何把 state 转变成下一个 state。
     *
     * state 的形式取决于你,可以是基本类型、数组、对象、
     * 甚至是 Immutable.js 生成的数据结构。惟一的要点是
     * 当 state 变化时需要返回全新的对象,而不是修改传入的参数。
     *
     * 下面例子使用 `switch` 语句和字符串来做判断,但你可以写帮助类(helper)
     * 根据不同的约定(如方法映射)来判断,只要适用你的项目即可。
     */
    
    function countReducer(state = 0,action){
        console.log(`state:${state}---action:${action}---type:${action.type}`);
        switch (action.type){
            case 'INCREMENT':
                return state + 1;
            case 'DECREMENT':
                return state - 1;
            default:
                return state;
        }
    }
    export default countReducer;
    
  • store.js

    import { createStore } from 'redux';
    
    import countReducer from './countReducer.js'
    
    const store = createStore(countReducer);
    
    export default store;
    
  • CountNumRedux.jsx

    import { useState,useEffect } from "react";
    import store from '../redux/store'
    
    function CountNumRedux(){
    
        const [count,setCount] = useState(0);
    
        function add(){
            // setCount(count => count+1);
            //派发action 改变内部 state 惟一方法是 dispatch 一个 action。
            store.dispatch({ type: 'INCREMENT' });
        }
    
        function subtract(){
            // setCount(count => count-1);
            store.dispatch({ type: 'DECREMENT' });
        }
    
        // 可以手动订阅更新,也可以事件绑定到视图层。
        // store.subscribe(() =>
        //     console.log('订阅更新,打印1-----',store.getState())
        // );
    
        useEffect(()=>{
            store.subscribe(()=>{
                console.log('订阅更新,打印2-----',store.getState());
                setCount(store.getState());
            });
        });
    
    
        return(
            <div>
                当前数字是:{count}    &nbsp;&nbsp;&nbsp;&nbsp;
                当前数字是:{store.getState()}  
                <br /><br />
    
                <button onClick={add}>点我 +1</button> <br /><br />
                <button onClick={subtract}>点我 -1</button>
            </div>
        )
    }
    
    export default CountNumRedux;
    

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

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

相关文章

【算法】二分答案

文章目录 相关链接什么时候使用二分答案&#xff1f;题目列表最大化最小化相关题目列表&#x1f4d5;2439. 最小化数组中的最大值解法1——二分答案解法2——分类讨论O(n) 2513. 最小化两个数组中的最大值&#xff08;二分答案lcm容斥原理&#xff09;&#x1f402;好题&#x…

每日练习-8

目录 一、选择题 二、算法题 1.另类加法 2、走方格的方案数 一、选择题 1、 解析&#xff1a;当使用new运算符创建一个类的对象数组时&#xff0c;会调用该类的构造函数来初始化每个对象。因此&#xff0c;如果创建了5个对象&#xff0c;那么构造函数会被调用5次。 当使用delet…

[2023.09.20]:Yew的前端开发经历小结

今天基本上完成了一个操作闭环&#xff0c;即能够保存&#xff0c;拉取和删除数据。截个图 这个过程的前端和后端都是用Rust写的&#xff0c;前端使用的是Yew。 Yew是一种用于构建现代Web应用程序的Rust框架&#xff0c;其计目标是提供一种安全、高效、易用的方式来构建Web应…

智慧公厕:改变公共厕所管理与运营的未来

在现代社会中&#xff0c;公共厕所是城市建设的重要组成部分。然而&#xff0c;长期以来&#xff0c;公共厕所管理与运营一直是一个令人头疼的问题。由于各种原因&#xff0c;公共厕所常常陷入管理难、环境差、设备设施陈旧的状态&#xff0c;给人们的生活带来困扰。然而&#…

【性能优化下】组织结构同步优化二,全量同步/增量同步,断点续传实现方式

看到这一篇文章的 xdm &#xff0c;应该对组织结构同步有一些想法了吧&#xff0c;如果没有&#xff0c;可以看前面两篇文章&#xff0c;可以通过如下地址查看一下&#xff1a; 【性能优化上】第三方组织结构同步优化一&#xff0c;你 get 到了吗&#xff1f; 坑爹&#xff0c…

Java中synchronized:特性、使用、锁机制与策略简析

目录 synchronized的特性互斥性可见性可重入性 synchronized的使用方法synchronized的锁机制常见锁策略乐观锁与悲观锁重量级锁与轻量级锁公平锁与非公平锁可重入锁与不可重入锁自旋锁读写锁 synchronized的特性 互斥性 synchronized确保同一时间只有一个线程可以进入同步块或…

函数扩展之——内存函数

前言&#xff1a;小伙伴们又见面啦。 本篇文章&#xff0c;我们将讲解C语言中比较重要且常用的内存函数&#xff0c;并尝试模拟实现它们的功能。 让我们一起来学习叭。 目录 一.什么是内存函数 二.内存函数有哪些 1.memcpy &#xff08;1&#xff09;库函数memcpy &…

交换机端口镜像详解

交换机端口镜像是一种网络监控技术&#xff0c;它允许将一个或多个交换机端口的网络流量复制并重定向到另一个端口上&#xff0c;以便进行流量监测、分析和记录。通过端口镜像&#xff0c;管理员可以实时查看特定端口上的流量&#xff0c;以进行网络故障排查、安全审计和性能优…

已解决 Microservice Error: Circuit Breaker: Service is temporarily unavailable

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页: &#x1f405;&#x1f43e;猫头虎的博客&#x1f390;《面试题大全专栏》 &#x1f995; 文章图文并茂&#x1f996…

【操作系统】聊聊磁盘IO是如何工作的

磁盘 机械磁盘 主要是由盘片和读写磁头组成。数据存储在盘片的的环状磁道上&#xff0c;读写数据前需要移动磁头&#xff0c;先找到对应的磁道&#xff0c;然后才可以访问数据。 如果数据都在同一磁道上&#xff0c;不需要在进行切换磁道&#xff0c;这就是连续IO&#xff0c;可…

离散数学之 一阶逻辑等值演算与推理

一阶逻辑等值式与置换规则 基本等值式 这里用到了量词辖域的收缩 未完待续

电工三级证(高级)实战项目:PLC控制步进电机正反转

实训目的 了解使用PLC代替传统继电器控制回路的方法及编程技巧&#xff0c;理解并掌握步进电动机的运行方式及其实现方法。通过实验进一步加深理解步进电机控制的特点以及在实际中的应用。 控制要求 PLC设备:Siemens S7-200 要求:打开开关K0(I0.0)得电&#xff0c;启动PLC程…

【xshell和xftp连接Ubuntu教程】

一、下载xshell和xftp 下载地址 https://www.xshell.com/zh/free-for-home-school/ 二、连接xshell 输入ip&#xff0c;端口号 输入用户名&#xff0c;密码 出现这个使用就行了 三、连接xftp 同上&#xff0c;输入ip&#xff0c;端口&#xff0c;用户名&#xff0c;密码 连接成…

拓扑关系如何管理?

在设备对接涂鸦的云端过程中&#xff0c;一部分设备由于自身资源或硬件配置&#xff0c;无法直接连接云端。而是需要通过网关进行中转&#xff0c;由网关代理实现和云端进行数据交互&#xff0c;间接实现设备接入云端。这样的设备也称为子设备。 要想实现网关代理子设备接入云…

C++跳坑记:位移超出范围的处理

在C编程中&#xff0c;数据类型的选择不仅影响内存占用和性能&#xff0c;还可以对某些操作的结果产生意想不到的影响。今天&#xff0c;我将分享一个关于C在不同变量类型下位移操作结果的发现。 位移操作是C中常见的对整数的高效操作之一。然而&#xff0c;我们可能会忽视一个…

单播与多播mac地址

MAC 地址&#xff08;Media Access Control Address&#xff09;是一个用于识别网络设备的唯一标识符。每个网络设备都有一个独特的 MAC 地址&#xff0c;用于在局域网中进行通信。 单播MAC地址&#xff1a;单播MAC地址用于单播通信&#xff0c;即一对一的通信模式。当设备发送…

day4_QT

day4_QT qt绘制钟表 qt绘制钟表 #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);this->resize(1000,1000);this->setStyleSheet("background-color:…

Word中对象方法(Methods)的理解及示例(下)

【分享成果&#xff0c;随喜正能量】当你的见识多了&#xff0c;眼界宽了&#xff0c;格局大了&#xff0c;所有的磨难都将不再是磨难&#xff0c;而是助你成长的阶梯。 。 《VBA之Word应用》&#xff08;10178982&#xff09;&#xff0c;是我推出第八套教程&#xff0c;教程…

pnpm入门教程

一、概述 1、更小 使用 npm 时&#xff0c;依赖每次被不同的项目使用&#xff0c;都会重复安装一次。 而在使用 pnpm 时&#xff0c;依赖会被存储在内容可寻址的存储中。 2、更快 依赖解析。 仓库中没有的依赖都被识别并获取到仓库。目录结构计算。 node_modules 目录结构是…

编程(47)----------Spring AOP

AOP是Spring中, 个人认为较为抽象的一个思想. 一般来说, 学习一个新东西, 第一件事是先看看这个知识点的定义是什么. 同时要注意, 同一事物的定义可以有很多, 毕竟定义没有绝对的对与错, 只有准确与否. 而初次接触AOP的定义, 第一感觉可能就是抽象, 或者说看不懂, 这里面也有…