【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://www.rhkb.cn/news/384553.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Redis】主从复制分析-基础

1 主从节点运行数据的存储 在主从复制中, 对于主节点, 从节点就是自身的一个客户端, 所以和普通的客户端一样, 会被组织为一个 client 的结构体。 typedef struct client {// 省略 } client;同时无论是从节点, 还是主节点, 在运行中的数据都存放在一个 redisServer 的结构体中…

使用C#手搓Word插件

WordTools主要功能介绍 编码语言&#xff1a;C#【VSTO】 1、选择 1.1、表格 作用&#xff1a;全选文档中的表格&#xff1b; 1.2、表头 作用&#xff1a;全选文档所有表格的表头【第一行】&#xff1b; 1.3、表正文 全选文档中所有表格的除表头部分【除第一行部分】 1.…

Vue常用指令及其生命周期

作者&#xff1a;CSDN-PleaSure乐事 欢迎大家阅读我的博客 希望大家喜欢 目录 1.常用指令 1.1 v-bind 1.2 v-model 注意事项 1.3 v-on 注意事项 1.4 v-if / v-else-if / v-else 1.5 v-show 1.6 v-for 无索引 有索引 生命周期 定义 流程 1.常用指令 Vue当中的指令…

福派斯牛肉高脂猫粮,为何成猫舍首选?揭秘其神奇功效!

&#x1f43e; 说到猫咪的伙食&#xff0c;咱们当铲屎官的可是操碎了心&#xff01;想让自家毛孩子吃得健康又开心&#xff0c;选对猫粮真的太重要了。今天就来聊聊为啥福派斯牛肉高脂猫粮能成为众多猫舍的首选&#xff0c;以及它到底能帮咱们的小猫咪哪些忙吧&#xff01; 1️…

数据传输安全--SSL VPN

目录 IPSEC在Client to LAN场景下比较吃力的表现 SSL VPV SSL VPN优势 SSL协议 SSL所在层次 SSL工作原理 SSL握手协议、SSL密码变化协议、SSL警告协议三个协议作用 工作过程 1、进行TCP三次握手、建立网络连接会话 2、客户端先发送Client HELLO包&#xff0c;下图是包…

springboot项目从jdk8升级为jdk17过程记录

背景&#xff1a;公司有升级项目jdk的规划&#xff0c;计划从jdk8升级到jdk11 开始 首先配置本地的java_home 参考文档&#xff1a;Mac环境下切换JDK版本及不同的maven-CSDN博客 将pom.xml中jdk1.8相关的版本全部改为jdk17&#xff0c;主要是maven编译插件之类的&#xff0c…

ubuntu22.04 安装 NVIDIA 驱动以及CUDA

目录 1、事前问题解决 2、安装 nvidia 驱动 3、卸载 nvidia 驱动方法 4、安装 CUDA 5、安装 Anaconda 6、安装 PyTorch 1、事前问题解决 在安装完ubuntu之后&#xff0c;如果进入ubuntu出现黑屏情况&#xff0c;一般就是nvidia驱动与linux自带的不兼容&#xff0c;可以通…

找工作准备刷题Day10 回溯算法 (卡尔41期训练营 7.24)

回溯算法今天这几个题目做过&#xff0c;晚上有面试&#xff0c;今天水一水。 第一题&#xff1a;Leetcode77. 组合 题目描述 解题思路 从题目示例来看&#xff0c;k个数是不能重合的&#xff0c;但是题目没有明确说明这一点。 使用回溯算法解决此问题&#xff0c;利用树形…

数据结构 —— B+树和B*树及MySQL底层引擎

数据结构 —— B树和B*树及MySQL底层引擎 B树B*树B树的应用B树在MySQL中的应用MyISAMInnoDB 我们之前学习了B树的基本原理&#xff0c;今天我们来看看B树的一些改良版本——B树和B*树。如果还没有了解过的小伙伴可以点击这里&#xff1a; https://blog.csdn.net/qq_67693066/ar…

【MySQL进阶之路 | 高级篇】MVCC三剑客:隐藏字段,Undo Log,ReadView

1. 再谈隔离级别 我们知道事务有四个隔离级别&#xff0c;可能存在三种并发问题&#xff1a; 在MySQL中&#xff0c;默认的隔离级别是可重复读&#xff0c;可以解决脏读和不可重复读的问题&#xff0c;如果仅从定义的角度来看&#xff0c;它并不能解决幻读问题。如果我们想要解…

Nacos-2.4.0最新版本docker镜像,本人亲自制作,部署十分方便,兼容postgresql最新版本17和16,奉献给大家了

基于Postgresql数据库存储的nacos最新版本2.4.0,采用docker镜像安装方式 因业务需要,为了让nacos支持postgresql,特意花了两天时间修改了源码,然后制作了docker镜像,如果你也在找支持postgresql的nacos最新版本,恭喜你,你来的正好~ nacos-2.4.0 postgresql的数据库脚本…

安宝特方案|解放双手,解决死角,AR带来质量监督新体验

AR质量监督 解放双手&#xff0c;解决死角 在当今制造业快速发展的背景下&#xff0c;质量监督成为确保产品高质量和完善的管理制度的关键环节。然而&#xff0c;传统的质量监督方式存在诸多挑战&#xff0c;如人工操作带来的效率低下、查岗不及时、摄像头死角等问题。 为了解…

本地部署,Whisper: 开源语音识别模型

目录 简介 特点 应用 使用方法 总结 GitHub - openai/whisper: Robust Speech Recognition via Large-Scale Weak SupervisionRobust Speech Recognition via Large-Scale Weak Supervision - openai/whisperhttps://github.com/openai/whisper 简介 Whisper 是一个由 O…

GoogleCTF2023 Writeup

GoogleCTF2023 Writeup Misc NPC Crypto LEAST COMMON GENOMINATOR? Web UNDER-CONSTRUCTION NPC A friend handed me this map and told me that it will lead me to the flag. It is confusing me and I don’t know how to read it, can you help me out? Attach…

软件更新的双刃剑:从”微软蓝屏”事件看网络安全的挑战与对策

引言 原文链接 近日&#xff0c;一场由微软视窗系统软件更新引发的全球性"微软蓝屏"事件震惊了整个科技界。这次事件源于美国电脑安全技术公司"众击"提供的一个带有"缺陷"的软件更新&#xff0c;如同一颗隐形炸弹在全球范围内引爆&#xff0c;…

17.5【C语言】static的补充说明

static &#xff08;静态的) 作用&#xff1a;修饰局部变量&#xff0c;修饰全局变量&#xff0c;修饰函数 对比两段代码 #include <stdio.h> void test() {int a 5;a;printf("%d ", a); } int main() {int i 0;for(i0; i<5; i){test();}return 0; } …

高并发内存池——链表设计

自由链表类的设计 由于申请的空间块经过对齐之后大小至少为8&#xff0c;因此可以考虑在未被使用的内存块中取前8字节存储下一个空间的地址 FreeList类初步声明 class FreeList { private:void* _freelistnullptr; //自由链表头指针size_t _size0; //自由链表的长度size_t …

【Django】anaconda环境变量配置及配置python虚拟环境

文章目录 配置环境变量配置python虚拟环境查看conda源并配置国内源在虚拟环境中安装django 配置环境变量 control sysdm.cpl,,3笔者anaconda安装目录为C:\ProgramData\anaconda3 那么需要加入path中的有如下三个 C:\ProgramData\anaconda3 C:\ProgramData\anaconda3\Scripts C:…

最新风车IM即时聊天源码及完整视频教程2024年7月版

堡塔面板 试验性Centos/Ubuntu/Debian安装命令 独立运行环境&#xff08;py3.7&#xff09; 可能存在少量兼容性问题 不断优化中 curl -sSO http://io.bt.sy/install/install_panel.sh && bash install_panel.sh 1.宝塔环境如下: Nginx 1.20 Tomcat 8 MySQL 8.0 R…

Java 开发环境配置

1. 下载 JDK 直接在oracle 官网下载 https://www.oracle.com/java/technologies/downloads或者使用博主已经从oracle下载的 jdk21&#xff1a;https://download.csdn.net/download/u011171506/89585231jdk8&#xff1a;https://download.csdn.net/download/u011171506/8958523…