Redux-状态管理组件

一、简介

        react中的状态只属于某个组件。而Redux是一个全局管理js状态的架构,让组件通信更加容易。

之前是状态在所有组件间传递,而redux通过store来实现这个功能。

Redux特性:

1.Single source Of truth,通过store唯一维护状态。

2.可预测性,state + action -> new state

3.纯函数更新store (纯函数 -> 输入决定输出)

举个例子: 待办事项表

function todos(state = [], action){
    switch(action.type){
        case 'ADD_TODO':
            return state.concat([{text: action.text, completed: false}]);
        case 'TOGGLE_TODO':
            return state.map(
                (todo, idx) => {
                    action.index === idx ? {text: todo.text, completed: !toto.completed}
                    : todo
                }
            )
        default:
            return state
        
    }

}

二、核心概览

拿上图举个例子,前端ui产生了deposit和withdraw2个事件,store通过dispatcher分发对应的事件给reducer处理,reducer处理后更新state。前端ui根据state重新渲染。

1.store

Redux的状态机实现,store 通过state存储状态,通过dispatch传播事件,通过Reducer处理事件。

2.action

        action表示变更事件。一般包含event type 和 context。

3.Reducer

        reducer是状态事件处理。

举个例子: 待办事项表

function todoApp(state = initialState, action){
    switch (action.type){
        case ADD_TODO:
            return Object.assign({}, state, {
                todos:[
                    ...state.todos,
                    {
                        text: action.text,
                        completed: false
                    }
                ]
            });
        default:
            return state;
        
    }
}

三、使用示例

用redux实现一个简单计数器,包括增加、减少功能。

import React from 'react';
import {createStore} from 'redux';
function run(){
    // store initial state
    const initialState = { count: 0};
    // reducer
    const counter = (state = initialState, action) => {
        switch (action.type){
            case "PLUS_ONE":
                return {count: state.count + 1};
            case "MiNUS_ONE":
                return {count: state.count - 1};
            case "CUSTOM_COUNT":
                return {
                    count: state.count + action.payload.count
                };
            default:
              return state;
        }  
    }
    // create store
    const store = createStore(counter);
    // Action creator
    function plusOne(){
        return {type: "PLUS_ONE"}
    }
    
    function minusOne(){
        return {type: "MINUS_ONE"};
    }
    function customCount(count){
        return {type: "CUSTOM_COUNT", payload:{count}};
    }
    // 订阅redux 状态变更
    store.subscribe(() => console.log(store.getState()));
    store.dispatch(plusOne());
    store.dispatch(minusOne());
    store.dispatch(customCount(5));
}

export default ()  => {
    <div>
        <button onClick={run}>Run</button>
        <p>* 请打开控制台查看运行结果</p>
    </div>
}

bindActionCreators使用,工具类,可以减少显示dispatch操作

import React from 'react';
import {createStore, bindActionCreators} from 'redux';
function run(){
    // store initial state
    const initialState = { count: 0};
    // reducer
    const counter = (state = initialState, action) => {
        switch (action.type){
            case "PLUS_ONE":
                return {count: state.count + 1};
            case "MiNUS_ONE":
                return {count: state.count - 1};
            case "CUSTOM_COUNT":
                return {
                    count: state.count + action.payload.count
                };
            default:
              return state;
        }  
    }
    // create store
    const store = createStore(counter);
    // Action creator
    function plusOne(){
        return {type: "PLUS_ONE"}
    }
    
    function minusOne(){
        return {type: "MINUS_ONE"};
    }
    function customCount(count){
        return {type: "CUSTOM_COUNT", payload:{count}};
    }

    plusOne = bindActionCreators(plusOne, store.dispatch);
    minusOne = bindActionCreators(minusOne, store.dispatch);
    customCount = bindActionCreators(customCount, store.dispatch);
    // 订阅redux 状态变更
    store.subscribe(() => console.log(store.getState()));
    plusOne();
    minusOne();
    customCount(5);
}

export default ()  => {
    <div>
        <button onClick={run}>Run</button>
        <p>* 请打开控制台查看运行结果</p>
    </div>
}

四、结合React使用

使用Connect功能,将redux的action和state作为props传递给组件。

计数器组件使用样例

import React from 'react';
import {createStore, bindActionCreators} from 'redux';
import {Provider, connect} fomr 'react-redux';

// store initial state
const initialState = {count: 0};

// reducer
const counter = (state = initialState, action) => {
        switch (action.type){
            case "PLUS_ONE":
                return {count: state.count + 1};
            case "MiNUS_ONE":
                return {count: state.count - 1};
            case "CUSTOM_COUNT":
                return {
                    count: state.count + action.payload.count
                };
            default:
              return state;
        }  
}
// create store
const store = createStore(counter);
// Action creator
function plusOne(){
   return {type: "PLUS_ONE"}
}
function minusOne(){
        return {type: "MINUS_ONE"};
}

export class Counter extends React.Component{
    render(){
        const {count, plusOne, minusOne} = this.props;
        return (
            <div className = "counter">
                <button onClick = {minusOne}>-</button>
                <span>{count}</span>
                <button onClick = {plusOne}>+</button>
             </div>
        );
    }
}


// 将store的state与组件props绑定
function mapStateToProps(state){
    return {
        count: state.count
    };
}

// 将store的action与组件props绑定
function mapDispatchToProps(dispatch){
    return bindActionCreators({plusOne, minusOne}, dispatch)
}


// 通过connect组件将store与counter组件关联
const ConnectedCounter = connect(mapStateToProps, mapDispatchToProps)(Counter) ;

// 返回使用样例
export default class CounterSample extends React.Component{
    render(){
        return (
            // prodiver 基于react context实现,可以让里面的子组件都能获取到store
            <Provider store = {store}>
                <ConnectedCounter/>
            </Provider>
        );
    }
}


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

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

相关文章

基于单片机16路抢答器仿真系统

**单片机设计介绍&#xff0c; 基于单片机16路抢答器仿真系统 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机的16路抢答器仿真系统是一种用于模拟和实现抢答竞赛的系统。该系统由硬件和软件两部分组成。 硬件方面&am…

Java21新增特性

版本介绍 Java 21是Java平台的一个新版本&#xff0c;于2023年9月19日由Oracle公司正式发布。这个版本包含了数千个性能、稳定性和安全性更新&#xff0c;以及几十个新功能和增强。其中&#xff0c;15个增强被赋予了自己的JDK增强提案&#xff08;JEP&#xff09;&#xff0c;…

超详细~25考研规划~感恩现在努力的你!!!

25考研规划 俄语&#xff0c;翻译过来叫我爱你 考试时间 第一天 8.30-11.30政治——100分 2.00-5.00英语——100分 第二天 8.30-11.30数学——150分 2.00-5.00专业课——150分 1.什么是25考研 将在2024年12月参加考研&#xff0c;2025年本科毕业&#xff0c;9月读研究…

【Linux】第十九站:进程替换

文章目录 一、单进程版---最简单的程序替换二、进程替换的原理三、多进程的程序替换1.多进程的程序替换实例2.那么程序在替换时候有没有创建子进程呢3.再谈原理4.一个现象5.我们的CPU如何得知程序的入口地址&#xff1f; 四、各个接口的介绍1.execl2.execlp3.execv4.execvp5.ex…

java文件压缩加密,使用流的方式

使用net.lingala.zip4j来进行文件加密压缩。 添加依赖net.lingala.zip4j包依赖&#xff0c;这里使用的是最新的包2.11.5版本。 <dependency><groupId>net.lingala.zip4j</groupId><artifactId>zip4j</artifactId><version>${zip4j.versi…

某60区块链安全之不安全的随机数实战一

区块链安全 文章目录 区块链安全不安全的随机数实战一实验目的实验环境实验工具实验原理实验内容攻击过程分析合约源代码漏洞EXP利用 不安全的随机数实战一 实验目的 学会使用python3的web3模块 学会以太坊不安全的随机数漏洞分析及利用 实验环境 Ubuntu18.04操作机 实验工…

进程之理解进程的概念

你必须非常努力&#xff0c;才能看起来毫不费力。文章目录 进程的基本概念描述进程——pcbtest_struct pcb的一种task_struct 内容分类 组织进程查看进程通过系统调用获取进程标示符总结 进程的基本概念 课本概念&#xff1a;进程是一个执行实列&#xff0c;正在执行的程序等。…

JAVA小游戏拼图

第一步是创建项目 项目名自拟 第二部创建个包名 来规范class 然后是创建类 创建一个代码类 和一个运行类 代码如下&#xff1a; package heima; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import …

一款实用的.NET Core加密解密工具类库

前言 在我们日常开发工作中&#xff0c;为了数据安全问题对数据加密、解密是必不可少的。加密方式有很多种如常见的AES&#xff0c;RSA&#xff0c;MD5&#xff0c;SAH1&#xff0c;SAH256&#xff0c;DES等&#xff0c;这时候假如我们有一个封装的对应加密解密工具类可以直接…

源码分析Mybatis拦截器(Interceptor)拦截saveBatch()获取不到实体id的原因

1.背景 由于业务需求想在Mybatis拦截器层面获取insert后实体id去做相关业务。但是发现执行saveBatch()方法时&#xff0c;获取参数实体的时候&#xff0c;拿不到自增id。但是save()方法可以。 save方法之所以可以是因为&#xff1a; MybatisPlus的BaseMapper执行insert方法后…

leetcode刷题日志-68.文本左右对齐

给定一个单词数组 words 和一个长度 maxWidth &#xff0c;重新排版单词&#xff0c;使其成为每行恰好有 maxWidth 个字符&#xff0c;且左右两端对齐的文本。 你应该使用 “贪心算法” 来放置给定的单词&#xff1b;也就是说&#xff0c;尽可能多地往每行中放置单词。必要时可…

C语言:结构体

目录 结构体类型的声明 匿名结构体 全局结构体变量 嵌套结构体 访问结构体成员 结构的自引用 结构体变量的定义和初始化 结构体内存对齐 结构体内存对齐规则 修改默认对齐数 #pragma pack(n) offsetof 求结构体成员相对于结构体开头的偏移量的宏。 为什么存在内存…

JavaScript 异步编程

异步的概念 异步&#xff08;Asynchronous, async&#xff09;是与同步&#xff08;Synchronous, sync&#xff09;相对的概念。 在我们学习的传统单线程编程中&#xff0c;程序的运行是同步的&#xff08;同步不意味着所有步骤同时运行&#xff0c;而是指步骤在一个控制流序…

【论文阅读】MAG:一种用于航天器遥测数据中有效异常检测的新方法

文章目录 摘要1 引言2 问题描述3 拟议框架4 所提出方法的细节A.数据预处理B.变量相关分析C.MAG模型D.异常分数 5 实验A.数据集和性能指标B.实验设置与平台C.结果和比较 6 结论 摘要 异常检测是保证航天器稳定性的关键。在航天器运行过程中&#xff0c;传感器和控制器产生大量周…

六大排序(插入排序、希尔排序、冒泡排序、选择排序、堆排序、快速排序)未完

文章目录 排序一、 排序的概念1.排序&#xff1a;2.稳定性&#xff1a;3.内部排序&#xff1a;4.外部排序&#xff1a; 二、插入排序1.直接插入排序2.希尔排序 三、选择排序1.直接选择排序方法一方法二直接插入排序和直接排序的区别 2.堆排序 四、交换排序1.冒泡排序2.快速排序…

论文阅读——DiffusionDet

在目标检测上使用扩散模型 前向过程&#xff1a;真实框-->随机框 后向过程&#xff1a;随机框-->真实框 前向过程&#xff1a; 一般一张图片真实框的数目不同&#xff0c;填补到同一的N个框&#xff0c;填补方法可以是重复真实框&#xff0c;填补和图片大小一样的框&a…

Hive语法,函数--学习笔记

1&#xff0c;排序处理 1.1cluster by排序 &#xff0c;在Hive中使用order by排序时是全表扫描&#xff0c;且仅使用一个Reduce完成。 在海量数据待排序查询处理时&#xff0c;可以采用【先分桶再排序】的策略提升效率。此时&#xff0c; 就可以使用cluster by语法。 cluster…

从能用到好用,国产CPU不是你想象中的样子了?

最近看到了挺多关于国产CPU的评测视频&#xff0c;主要测试了鲲鹏、飞腾、海光、龙芯这四家。作为信创从业者&#xff0c;也想结合日常工作中接触到的国产CPU使用体验&#xff0c;发表些自己的看法。 我看到的评测&#xff0c;主要是采用SPEC CPU2006进行横向对比。SPEC CPU20…

VMware Workstation 与 Device/Credential Guard 不兼容 解决办法

问题描述 问题描述&#xff1a; VMware 启动虚拟机会报错。无法运行。 错误信息&#xff1a;VMware Workstation 与 Device/Credential Guard 不兼容。在禁用 Device/Credential Guard 原因分析&#xff1a; 通常原因是 Window 系统开启了 内置的Hyper-V 虚拟机。 解决方案&…

在 Linux 上搭建 Java Web 项目环境(最简单的进行搭建)

要在 Linux 上安装的程序有 1.JDK (要想运行 java 程序 JDK 是必不可少的) 2.Tomcat &#xff08;HTTP 服务器&#xff0c;是管理 Web 项目的常用工具&#xff09; 3. mysql &#xff08;数据库&#xff09; 一.安装 JDK 博主使用的 Linux 发行版是 centos &#xff0c;cen…