如何react中使用redux和react-redux

news2024/11/18 1:40:21

Redux

Redux 是 JavaScript 状态容器,提供可预测化的状态管理。

可以让你构建一致化的应用,运行于不同的环境(客户端、服务器、原生应用),并且易于测试。

不仅于此,它还提供 超爽的开发体验,比如有一个时间旅行调试器可以编辑后实时预览。

Redux 除了和 React 一起用外,还支持其它界面库。 它体小精悍(只有2kB,包括依赖)。

  • 英文原版:http://redux.js.org/
  • Redux 中文文档: https://cn.redux.js.org/
  • Redux 中文文档:https://www.redux.org.cn/

Redux Flow

三大原则

同步

官网地址:https://cn.redux.js.org/tutorials/essentials/part-1-overview-concepts

异步

官网地址:https://cn.redux.js.org/tutorials/essentials/part-5-async-logic

查看原图

react中使用redux

我们使用redux处理一个问题,点击按钮,实现左侧导航的展开与闭合,如下图:

查询文档,可知:点击按钮,修改Sider容器的collapsed属性为true,即可满足要求。

但是,由于头部部分按钮和改Sider容器不在一个组件,故此,就出现了兄弟组件的通信问题

安装组件

安装 reduxreact-redux

yarn add redux react-redux

创建redux文件夹及其他文件

创建的目录如下:

创建store

在redux文件夹下面,新建store.js用于创建store

import { createStore } from 'redux'
import { SidebarCollapsedReducers } from "./reducers/SidebarCollapsedReducers"; 

let store = createStore(SidebarCollapsedReducers)

我们在项目中,不可能只有一个Reducer。

随着应用变得越来越复杂,可以考虑将 reducer 函数 拆分成多个单独的函数,拆分后的每个函数负责独立管理 state 的一部分。

所以,我们还会用到一个api-- combineReducers

combineReducers 辅助函数的作用是,把一个由多个不同 reducer 函数作为 value 的 object,合并成一个最终的 reducer 函数,然后就可以对这个 reducer 调用 createStore 方法。

合并后的 reducer 可以调用各个子 reducer,并把它们返回的结果合并成一个 state 对象。

由 combineReducers() 返回的 state 对象,会将传入的每个 reducer 返回的 state 按其传递给 combineReducers() 时对应的 key 进行命名。

示例

rootReducer = combineReducers({potato: potatoReducer, tomato: tomatoReducer})
// 这将返回如下的 state 对象
{
  potato: {
    // ... potatoes, 和一些其他由 potatoReducer 管理的 state 对象 ...
  },
  tomato: {
    // ... tomatoes, 和一些其他由 tomatoReducer 管理的 state 对象,比如说 sauce 属性 ...
  }
}

combineReducers

const reducer = combineReducers({
  SidebarCollapsedReducers,
});

改进store

import { createStore, combineReducers } from "redux";
import { SidebarCollapsedReducers } from "./reducers/SidebarCollapsedReducers"; // 导入 SidebarCollapsedReducers

const reducer = combineReducers({
  SidebarCollapsedReducers,
});
const store = createStore(reducer);

export default store; 

改进根组件

原先app.js

import IndexRouter from './router/IndexRouter' 
import './App.css' 
function App(){
  return <IndexRouter></IndexRouter>
  
}
export default App

引入 react-redux

改进app.js

import IndexRouter from './router/IndexRouter'
import {Provider} from 'react-redux'
import './App.css'
import store from './redux/store'
function App(){
  return <Provider store={store}> 
    <IndexRouter></IndexRouter>
  </Provider>
}
export default App

组件中使用

此功能涉及到两个组件:

  • TopHeader.js – 点击按钮部分 ,发布者
  • SideMenu.js – 订阅者

如下图

改造 TopHeader.js组件

// TopHeader.js

export default function TopHeader({ pageTitle }) {
// 其他代码
};

引入 react-redux,改进TopHeader.js

补充:connect()

react-redux 提供connect方法,用于从 UI 组件生成容器组件。connect的意思,就是将这两种组件连起来。

connect(
  mapStateToProps
  mapDispatchToProps   
)(被包装的组件)
  • mapStateToProps

将state映射到 UI 组件的参数(props)。 const mapStateToProps =state=> state;

  • mapDispatchToProps

将用户对 UI 组件的操作映射成 Action。

const  mapDispatchToProps = (dispatch)=>{    
  return {        
    'Increment':()=> dispatch(IncrementAction({})),        
    'Decrement':() => dispatch(DecrementAction({})),    
  }
}

改进TopHeader.js

import {connect} from 'react-redux'

function TopHeader({ pageTitle }) {

  const changeCollapsed = ()=>{
    // 改变state的状态 
    props.changeCollapsed() 
  }
       
  // 其他代码

  return <button  onClick={()=>changeCollapsed()}>操作</button>
};

const mapStateToProps = (state, ownProps) => { 
  return {
    isCollapsed: state.SidebarCollapsedReducers.isCollapsed
  }
}

const mapDispatchToProps = {
  changeCollapsed(){
    return {
      type: 'change_collapsed', 
    }
  }
}  

export default connect(mapStateToProps,mapDispatchToProps)(TopHeader);

同理,修改SideMenu.js

import {connect} from 'react-redux'

function SideBar(props) { 
  // 其他代码

  return <Sider collapsed={props.isCollapsed}></Sider> // 注意这里
};

const mapStateToProps = (state, ownProps) => { 
  return {
    isCollapsed: state.SidebarCollapsedReducers.isCollapsed
  }
}
 
export default connect(mapStateToProps)(SideBar);

总结 – 全部代码

\redux\reducers\SidebarCollapsedReducers.js

export const SidebarCollapsedReducers = (prevState = {
    isCollapsed: false
}, action) => { 
    switch (action.type) {
        case 'change_collapsed':
            let newState = {...prevState} // 注意这里
            newState.isCollapsed = !newState.isCollapsed
            return newState
        default:
            return prevState
    } 
};

\redux\store.js

import { createStore, combineReducers } from "redux";
import { SidebarCollapsedReducers } from "./reducers/SidebarCollapsedReducers"; // 导入 SidebarCollapsedReducers

const reducer = combineReducers({
  SidebarCollapsedReducers,
});
const store = createStore(reducer);

export default store;

app.js

import IndexRouter from './router/IndexRouter'
import {Provider} from 'react-redux'
import './App.css'
import store from './redux/store'
function App(){
  return <Provider store={store}> 
    <IndexRouter></IndexRouter>
  </Provider>
}
export default App

组件

components\sandbox\TopHeader.js

import React, { useEffect, useState } from "react";
import { Layout} from "antd"; 
import { connect } from "react-redux";
 
const { Header } = Layout;

function TopHeader(props) {   
  const changeCollapsed = ()=>{
    // 改变state的状态
    // dispatch
    console.log(props)
    props.changeCollapsed() 
  }

  return (
    <Header>
      <div style={{ display: "flex" }}>
        {React.createElement(
          props.isCollapsed ? MenuUnfoldOutlined : MenuFoldOutlined,
          {
            className: styles.trigger,
             onClick: () => changeCollapsed()
          }
        )} 
      </div> 
    </Header>
  );
}

const mapStateToProps = (state, ownProps) => { 
  return {
    isCollapsed: state.SidebarCollapsedReducers.isCollapsed
  }
}

const mapDispatchToProps = {
  changeCollapsed(){
    return {
      type: 'change_collapsed', 
    }
  }
}  
export default connect(mapStateToProps,mapDispatchToProps)(TopHeader);

components\sandbox\SideMenu.js

import { useEffect, useState } from "react";
import { Layout, Menu } from "antd"; 
import { connect } from "react-redux";

const { Sider } = Layout;

function AppLayout(props) {  
  return ( 
      <Sider trigger={null} collapsible collapsed={props.isCollapsed}> // 注意这里 props.isCollapsed
        <div className={styles.logo}> {siteBaseConfig.siteName} </div>
        ... 
      </Sider> 
  );
}

const mapStateToProps = (state, ownProps) => { 
  return {
    isCollapsed: state.SidebarCollapsedReducers.isCollapsed
  }
} 

export default connect(mapStateToProps)(AppLayout);

参考文档

  • https://cn.redux.js.org/api/combinereducers

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

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

相关文章

指针可以这样认知

注&#xff1a;此篇文章仅限初步了解&#xff0c;本小白后续会持续进行详解指针的相关操作。 目录&#xff1a; 认知内存一个内存单元的大小地址的产生 理解指针用途 指针变量的大小&#x1f49e;结尾 了解指针为什么需要了解内存呢&#xff1f; 因为指针是用来管理内存&#x…

【k8s】ruoyi微服务迁移到k8s

书接上回【传统方式部署Ruoyi微服务】&#xff0c;此刻要迁移至k8s。 环境说明 31 master &#xff0c; 32 node1 &#xff0c; 33 node2迁移思路 交付思路: 其实和交付到Linux主机上是一样的&#xff0c;无外乎将这些微服务都做成了Docker镜像; 1、微服务数据层: MySQL、 R…

聊聊 IP packet 的 TTL 与 tcp segment 的 MSL

聊聊 IP packet 的 TTL 与 tcp segment 的 MSL 1 前言 - 网络知识的重要性 近几年在排查解决应用系统在客户现场遇到的复杂问题时&#xff0c;越来越觉得除了扎实的LINUX操作系统知识&#xff0c;对TCP/IP网络知识的深入理解也是至关重要的。 有鉴于此&#xff0c;后续笔者会…

排序算法---插入排序

插入排序是一种简单的排序算法&#xff0c;一般又称为直接插入排序。插入排序的思想与选择排序有些相似&#xff0c;即在原数组上将数组分为两个部分&#xff1a;已排列好的有序数组和待排列数组&#xff0c;选择排序强调的是“选择”&#xff0c;而插入排序强调的是”插入“&a…

【Excel统计分析插件】上海道宁为您提供统计分析、数据可视化和建模软件——Analyse-it

Analyse-it是Microsoft Excel中的 统计分析插件 它为Microsoft Excel带来了 易于使用的统计软件 Analyse-it在软件中 引入了一些新的创新统计分析 Analyse-it与 许多Excel加载项开发人员不同 使用完善的软件开发和QA实践 包括单元/集成/系统测试 敏捷开发、代码审查 …

【JavaScript面向对象】

JavaScript面向对象 1 本节目标2 面向对象编程介绍2.1 两大编程思想2.2 面向过程编程POP2.3 面向对象编程OOP2.4 面向过程和面向对象的对比 3 ES6中的类和对象3.1 对象3.2 类class3.3 创建类3.4 类constructor构造函数3.5 类添加方法3.6 三个注意点 4 类的继承4.1 继承4.2 supe…

matlab 点云采样相关操作-源码复制粘贴即可

1.随机采样一个百分点的随机抽样 clc; clear; close all; % clear everything% Import point cloud pc pointCloud(Lion.xyz);% Plot all points pc.plot; % points are colored by z coordinate title(All Points, Color, w); view(0,0); snapnow;% Select randomly 5 perce…

FL Studio21免费吗?怎么下载最新中文版本?

FL Studio中文版已上线&#xff0c;自20.8版起已支持简体中文。推荐使用Windows 10系统安装&#xff0c; Windows 7系统设置FL Studio语言为中文时若出现乱码&#xff0c;可以将Win10系统中的“微软雅黑”字体复制并安装进Win7系统电脑中&#xff01;FL Studio支持什么格式的插…

【软考数据库】第四章 操作系统知识

目录 4.1 进程管理 4.1.1 操作系统概述 4.1.2 进程组成和状态 4.1.3 前趋图 4.1.4 进程同步与互斥 4.1.5 进程调度 4.1.6 死锁 4.1.7 线程 4.2 存储管理 4.2.1 分区存储管理 4.2.3 分页存储管理 4.2.…

进程与线程:同步和互斥

进程与线程&#xff1a;同步&互斥 同步&互斥的概念 ​ 进程具有异步性的特征。异步性是指各并发进程执行的进程的以各自独立的&#xff0c;不可预知的速度向前推进 同步 ​ 同步 亦称为直接制约关系&#xff0c;它是指为完成某种任务而建立的两个或多个进程&#xf…

虚拟主机解压/压缩功能说明

使用帮助说明 主机控制面板上点击文件管理&#xff0c;进入目录。 一、解压 windows操作系统: 鼠标移动到压缩文件&#xff0c;点击“解压” Linux操作系统&#xff1a; 压缩文件后点击解压按钮。 注意linux系统不支持rar在线解压&#xff0c;rar改名为zip也不能解压&…

JVM 调优

大部分的情况都是由于企业内部代码逻辑不合理导致。 JVM内部性能优化 栈上分配 方法内联 JVM的自适应调整 JVM改错 大并发内存不足OOM 内存泄漏GC频繁CPU飙升 JVM的调优的原则是让你各项指标尽可能的利用到你硬件的性能瓶颈。 JVM的性能优化可以分为代码层面和非代码层面。…

数据库系统工程师——第五章 网络基础知识

文章目录 &#x1f4c2; 第五章、网络基础知识 &#x1f4c1; 5.1 计算机网络概述 &#x1f4d6; 5.1.1 计算机网络的概念 &#x1f4d6; 5.1.2 计算机网络的分类 &#x1f4d6; 5.1.3 网络的拓扑结构 &#x1f4c1; 5.2 网络硬件基础 &#x1f4d6; 5.2.1 网络设备 &…

Linux 文件内容相关命令使用汇总

Linux操作系统有很多强大的文件内容相关命令&#xff0c;这些命令可以让您查看、分析和编辑文件。其中&#xff0c;最基本和常用的命令包括cat、more、less和head/tail等。除了这些基本命令之外&#xff0c;grep和find命令也是文件搜索和过滤方面的有力工具。 前言 我们这篇主…

UM2080F32 低功耗32 位 Sub1GHz 无线SOC收发器芯片

产品描述 UM2080F32 是广芯微电子&#xff08;广州&#xff09;股份有限公司研制的基于 ARM Cortex M0 内核的超低功 耗、高性能的、单片集成 (G)FSK/OOK 无线收发机的 32 位 S o C 芯片。 UM2080F32 工作于 200MHz~960MHz 范围内&#xff0c;支持灵活可设的数据包格式&#xf…

危险试探,产品经理赋予AI人格来打造品牌忠诚度

图片来源&#xff1a;由无界 AI工具生成 你可能不会相信&#xff0c;你的手机很可能变成你的虚拟情人&#xff0c;升级情人需要升级手机&#xff0c;而你从此再也不想换其他品牌手机。 AI时代&#xff0c;赋予产品以人格&#xff0c;让用户爱上产品&#xff0c;这或许是接下来产…

Python整个颜色小网站,给刚刚失恋的他.........

一些过场剧情: 死党一直暗恋校花&#xff0c;但是校花对他印象也不差&#xff0c; 就是死党一直太怂了&#xff0c;不敢去找校花&#xff0c; 直到昨天看到校花登上了校董儿子的豪车&#xff0c; 死党终于彻底死心&#xff0c;大醉一场&#xff0c;作为他的兄弟&#xff0c…

井电双控智能取水计量设备-井电双控遥测终端机

井电双控遥测终端机/井电双控智能取水计量设备&#xff08;MGTR-W4122C&#xff09;是针对取水计量控制系统开发智能终端产品。集预收费、流量监测、电量监测、余额提醒、欠费停机、无线传输、远程控制等多种功能于一体&#xff0c;并可根据项目需求选择实体IC卡和APP电子卡取水…

【JavaEE】从收发消息的角度理解 TCP/IP 五层网络模型的封装与分用

文章目录 1 为什么需要分层&#xff1f;2 TCP/IP 五层网络模型3 数据的封装&#xff08;发送消息为例&#xff09;4 数据的分用&#xff08;接收消息为例&#xff09;5 实际网络环境上的封装与分用写在最后 1 为什么需要分层&#xff1f; 你问我为啥需要分层&#xff1f;那必然…

python+vue 健康体检预约管理系统

该专门体检预约管理系统包括会员和管理员。其主要功能包括个人中心、会员管理、体检服务管理、类型管理、订单信息管理、取消订单管理、 体检报告管理、通知信息管理、交流论坛、系统管理等功能。 目 录 一、绪论 1 1.1研发背景和意义 2 1.2 国内研究动态 3 1.3论文主…