【React】详解 Redux 状态管理

文章目录

    • 一、Redux 的基本概念
      • 1. 什么是 Redux?
      • 2. Redux 的三大原则
    • 二、Redux 的核心组件
      • 1. Store
      • 2. Action
      • 3. Reducer
    • 三、Redux 的使用流程
      • 1. 安装 Redux 及其 React 绑定
      • 2. 创建 Action
      • 3. 创建 Reducer
      • 4. 创建 Store
      • 5. 在 React 应用中使用 Store
      • 6. 连接 React 组件与 Redux
    • 四、Redux 中间件
      • 1. redux-thunk
    • 五、Redux 的最佳实践
      • 1. 将代码模块化
      • 2. 使用组合 Reducers
      • 3. 使用 Selector

Redux 是一个用于 JavaScript 应用的状态管理库。它常与 React 搭配使用,但也可以与其他框架或原生 JavaScript 一起使用。Redux 提供了一个可预测的状态管理方式,使应用的状态更加透明和可控。本文将深入探讨 Redux 的基本概念、核心原理、使用方法及其在实际项目中的应用。通过本文,你将全面了解 Redux 的工作机制,并掌握如何在 React 项目中有效地使用 Redux。

一、Redux 的基本概念

1. 什么是 Redux?

Redux 是一个用于管理应用状态的 JavaScript 库。它的设计理念是将应用的所有状态存储在一个单一的、不可变的状态树(state tree)中。通过严格的状态管理和状态更新机制,Redux 使应用的状态变化更加可预测。

2. Redux 的三大原则

Redux 的三大原则是其核心理念,理解这些原则有助于更好地掌握 Redux 的使用。

(1) 单一数据源

整个应用的状态被存储在一个对象树中,这个对象树被存储在一个单一的 store 中。

(2) 状态是只读的

唯一改变状态的方法是触发一个 action,action 是一个描述发生了什么的对象。

(3) 使用纯函数进行状态更新

为了描述 action 如何改变 state 树,你需要编写 reducers。Reducer 是一些纯函数,它接受先前的 state 和 action,并返回新的 state。

二、Redux 的核心组件

Redux 的核心组件包括 Store、Action 和 Reducer。理解这些组件的作用和相互关系是掌握 Redux 的关键。

1. Store

Store 是整个 Redux 应用的状态存储中心。通过 createStore 函数创建 Store,应用中只能有一个 Store。

示例:创建 Store

import { createStore } from 'redux';
import rootReducer from './reducers';const store = createStore(rootReducer);

2. Action

Action 是一个描述事件的普通 JavaScript 对象。每个 action 必须有一个 type 属性,用于描述事件的类型,其他属性则用于传递事件相关的数据。

示例:定义 Action

const incrementAction = {type: 'INCREMENT',payload: {amount: 1}
};

3. Reducer

Reducer 是一个纯函数,接收当前的 state 和 action,返回新的 state。Reducer 根据 action 的 type 执行相应的状态更新逻辑。

示例:定义 Reducer

const initialState = { count: 0 };function counterReducer(state = initialState, action) {switch (action.type) {case 'INCREMENT':return { count: state.count + action.payload.amount };case 'DECREMENT':return { count: state.count - action.payload.amount };default:return state;}
}

三、Redux 的使用流程

了解了 Redux 的基本概念和核心组件后,我们来看看 Redux 的实际使用流程。以下是一个简单的示例,演示如何在 React 应用中使用 Redux。

1. 安装 Redux 及其 React 绑定

首先,我们需要安装 Redux 及其 React 绑定库 react-redux。

npm install redux react-redux

2. 创建 Action

定义一些 action,用于描述应用中可能发生的事件。

// actions.js
export const increment = (amount) => ({type: 'INCREMENT',payload: { amount }
});export const decrement = (amount) => ({type: 'DECREMENT',payload: { amount }
});

3. 创建 Reducer

定义 reducer 函数,用于根据 action 更新 state。

// reducers.js
const initialState = { count: 0 };function counterReducer(state = initialState, action) {switch (action.type) {case 'INCREMENT':return { count: state.count + action.payload.amount };case 'DECREMENT':return { count: state.count - action.payload.amount };default:return state;}
}export default counterReducer;

4. 创建 Store

使用 createStore 函数创建 Redux store,并将 reducer 传递给它。

// store.js
import { createStore } from 'redux';
import counterReducer from './reducers';const store = createStore(counterReducer);export default store;

5. 在 React 应用中使用 Store

使用 react-redux 提供的 Provider 组件将 Redux store 注入到 React 应用中。

// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import store from './store';
import App from './App';ReactDOM.render(<Provider store={store}><App /></Provider>,document.getElementById('root')
);

6. 连接 React 组件与 Redux

使用 react-redux 提供的 connect 函数将 React 组件与 Redux store 连接起来。

// Counter.js
import React from 'react';
import { connect } from 'react-redux';
import { increment, decrement } from './actions';function Counter({ count, increment, decrement }) {return (<div><p>Count: {count}</p><button onClick={() => increment(1)}>Increment</button><button onClick={() => decrement(1)}>Decrement</button></div>);
}const mapStateToProps = (state) => ({count: state.count
});const mapDispatchToProps = {increment,decrement
};export default connect(mapStateToProps, mapDispatchToProps)(Counter);

四、Redux 中间件

Redux 中间件用于在 action 发出之后,到达 reducer 之前,扩展 Redux 的功能。常用的中间件包括 redux-thunk 和 redux-saga。

1. redux-thunk

redux-thunk 是一个 Redux 中间件,允许你编写返回函数的 action creators。这个函数接收 dispatch 和 getState 作为参数,可以在其中执行异步操作。

示例:使用 redux-thunk 进行异步操作

// actions.js
export const fetchData = () => {return async (dispatch) => {const response = await fetch('https://api.example.com/data');const data = await response.json();dispatch({ type: 'SET_DATA', payload: data });};
};// reducers.js
const initialState = { data: [] };function dataReducer(state = initialState, action) {switch (action.type) {case 'SET_DATA':return { ...state, data: action.payload };default:return state;}
}// store.js
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import dataReducer from './reducers';const store = createStore(dataReducer, applyMiddleware(thunk));export default store;

五、Redux 的最佳实践

1. 将代码模块化

将 action、reducer 和组件分别放在不同的文件中,保持代码结构清晰。

2. 使用组合 Reducers

使用 combineReducers 将多个 reducer 组合在一起,管理复杂的应用状态。

import { combineReducers } from 'redux';
import counterReducer from './counterReducer';
import dataReducer from './dataReducer';const rootReducer = combineReducers({counter: counterReducer,data: dataReducer
});export default rootReducer;

3. 使用 Selector

使用 selector 函数从 state 中获取数据,避免在组件中直接访问 state。

// selectors.js
export const getCount = (state) => state.counter.count;
export const getData = (state) => state.data.data;// Counter.js
import { getCount } from './selectors';const mapStateToProps = (state) => ({count: getCount(state)
});

在这里插入图片描述

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

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

相关文章

网络通信---UDP

前两天做了个mplayer项目&#xff0c;今日继续学习 网络内容十分重要&#xff01;&#xff01;&#xff01; 1.OSI七层模型 应用层:要传输的数据信息&#xff0c;如文件传输&#xff0c;电子邮件等&#xff08;最接近用户&#xff0c;看传输的内容类型到底是什么&#xff09; …

【资料分享】2024第三届钉钉杯大学生大数据挑战赛B题思路解析+双语言代码

2024钉钉杯大学生大数据挑战赛&#xff0c;B题解题思路和双语言代码分享&#xff0c;资料预览&#xff1a;

jenkins参数化构建在UI中定义脚本中使用

先看配置&#xff1a; 流水线脚本&#xff1a; pipeline {agent {//label "${server}"label "${28}"}stages {stage(Hello) {steps {echo "--------------------------"// 只有这个可以输出变量echo "${character_argument}"echo &q…

瑞芯微芯片资料中关于图像处理相关的知识点

目录 MPI层模块介绍IPC的应用像素格式排布系统绑定API接口 MPI层 文件&#xff1a;Rockchip_Developer_Guide_MPI.pdf RK MPI&#xff1a;Rockchip Media Process Interface&#xff0c;媒体处理接口。 模块介绍 RK MPI层的模块介绍&#xff1a; IPC的应用 VI 模块捕获视频…

WordPress原创插件:自定义文章标题颜色

插件设置截图 文章编辑时&#xff0c;右边会出现一个标题颜色设置&#xff0c;可以设置为任何颜色 更新记录&#xff1a;从输入颜色css代码&#xff0c;改为颜色选择器&#xff0c;更方便&#xff01; 插件免费下载 https://download.csdn.net/download/huayula/89585192…

【一图流】Git下载与安装教程

下载Git Git官网&#xff1a;https://git-scm.com/?hlzh-cn 安装Git

IDEA git配置

1. git下载 您可以从git官方网站下载git。在https://git-scm.com/downloads下载页面上&#xff0c;您可以选择适用于您的操作系统的版本进行下载。 2、idea配置git(version control)

一步步教你学会如何安装VMare虚拟机(流程参考图)

前言&#xff1a;一步步教你安装VMare虚拟机&#xff08;此版本为17.5。2版本&#xff09;。 1、安装 2、确认协议 3、选择位置存放 4、选择第二个 5、都不选。 6、都选提供便捷操作 7、点击许可证&#xff0c;将密钥输入&#xff08;可以在网络寻找自己版本的密钥&#xff…

Linux定时器与时间轮 实现网络连接超时关闭

目录 原理理解 定时器超时触发可读事件机制 定时器 Linux定时器 Linux内核定时器API 时间轮 ​编辑 使用方法 时间轮与基于事件驱动配合 回调函数与定时器 梳理定时器加入到Reactor服务器的整体逻辑 EventLoop模块如何将新连接放入时间轮管理 新连接和定时器封装逻辑…

【系统架构设计师】十九、层次式架构设计理论与实践②

目录 四、数据访问层设计 4.1 数据访问模式 4.2 工厂模式在数据库访问层的应用 4.3 JavaBean中使用 JDBC 方式进行事务处理 4.4 连接对象管理设计 五、数据架构规划与设计 相关推荐 四、数据访问层设计 4.1 数据访问模式 数据访问模式有 5 种&#xff0c;分别是&#…

Ubuntu设置网络

进入网络配置文件夹 cd /etc/netplan 使用 vim 打开下的配置文件 打开后的配置 配置说明&#xff1a; network:# 网络配置部分ethernets:# 配置名为ens33的以太网接口ens33:addresses:# 为ens33接口分配IP地址192.168.220.30&#xff0c;子网掩码为24位- 192.168.220.30/24n…

爬虫 APP 逆向 ---> 粉笔考研

环境&#xff1a; 粉笔考研 v6.3.15&#xff1a;https://www.wandoujia.com/apps/1220941/history_v6031500雷电9 模拟器&#xff1a;https://www.ldmnq.com/安装 magisk&#xff1a;https://blog.csdn.net/Ruaki/article/details/135580772安装 Dia 插件 (作用&#xff1a;禁…

构建现代数据湖

现代数据湖是一半数据仓库和一半数据湖&#xff0c;对所有事情都使用对象存储。使用对象存储来构建数据仓库是通过 Open Table Formats OTF&#xff09; 实现的&#xff0c;例如 Apache Iceberg、Apache Hudi 和 Delta Lake&#xff0c;这些规范一旦实现&#xff0c;就可以无缝…

【proteus经典项目实战】51单片机用计数器中断实现100以内的按键计数并播放音乐

一、简介 一个基于8051微控制器的计数器系统&#xff0c;该系统能够通过按键输入递增计数&#xff0c;并且能够在达到100时归零。该系统将使用计数器中断和外部中断来实现其功能。 51单片机因其简单易用和成本效益高&#xff0c;成为电子爱好者和学生的首选平台。通过编程单片…

大数据学习之Flink基础

Flink基础 1、系统时间与时间时间 系统时间&#xff08;处理时间&#xff09; 在Sparksreaming的任务计算时&#xff0c;使用的是系统时间。 假设所用窗口为滚动窗口&#xff0c;大小为5分钟。那么每五分钟&#xff0c;都会对接收的数据进行提交任务. 但是&#xff0c;这里有…

项目都做完了,领导要求国际化????--JAVA后端篇

springboot项目国际化相信各位小伙伴都会&#xff0c;很简单&#xff0c;但是怎么项目都做完了&#xff0c;领导却要求国际化文件就很头疼了 国际化的SpringBoot代码&#xff1a; 第一步&#xff1a;创建工具类 /*** 获取i18n资源文件** author bims*/ public class Message…

循环队列的实现【C语言】

用数组实现循环队列 题目&#xff1a;622. 设计循环队列 - 力扣&#xff08;LeetCode&#xff09; 分析 循环队列&#xff0c;队列满则不能再插入数据&#xff0c;队列为空则不能再出数据。 多开一个空间方便区分队列为空和队列为满的情况。 如果要存K个数据只开K个空间&a…

IEC104转BACnet网关:实现电力监控与楼宇自动化的无缝对接

在电力监控和楼宇自控领域&#xff0c;IEC104和BACnet作为两种重要的通信协议扮演着重要的角色。随着不同系统之间的数据交换与集成需求的不断增长&#xff0c;深圳市钡铼技术有限公司推出IEC104转BACnet网关来实现这两种协议之间的无缝转换&#xff0c;助力电力监控和楼宇自控…

leetcode日记(47)螺旋矩阵Ⅱ

这题思路不难&#xff0c;就是找规律太难了。 我首先的思路是一行一行来&#xff0c;根据规律填入下一行的数组&#xff0c;第i行是由前i个数字&#xff08;n-2*i&#xff09;个增序数列后i个数字组成&#xff0c;后来觉得太难找规律了就换了一种思路。 思路大致是先计算出需…

C#、Net6、WebApi报表方案

目录 1 Pdf表单方案 1.1出现如下错误提示: 1.2 字体路径使用 2 Docx报表模板方案 2.1 pdf方案缺陷 2.2 解决方案 3 Spire.Doc报表方案 3.1 Docx方案缺陷 3.2 解决方案 4 插入复选框 5 WebApi文件流下载接口 6 软件获取方式 1 Pdf表单方案 使用【Adobe Acrobat P…