【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.mzph.cn/news/877183.shtml

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

相关文章

Docker安装oracle19c

文章目录 Docker安装oracle19c1. 拉取镜像2. 创建目录并赋权3. 构建容器并启动4. 查看日志5. 登录docker容器里面6. 登录sqlplus 创建PDB用户7. 查看show pdbs7. 切换数据库8. 创建用户9. 授权10. 使用navicat连接11. 参考和感谢 Docker安装oracle19c 1. 拉取镜像 docker pul…

深入分析 Android ContentProvider (八)

文章目录 深入分析 Android ContentProvider (八)ContentProvider 高级使用及最佳实践案例分析&#xff08;续&#xff09;1. 深入了解跨应用数据共享示例&#xff1a;跨应用数据共享的完整实现1. 定义权限2. 定义 ContentProvider3. ContentProvider 实现 2. 实践案例&#xf…

操作系统中存储系统简介 虚拟内存、内存管理、分页、保护

文章目录 存储器的层次结构存储器之间的实际价格和性能差距存储器的层次关系 虚拟内存简述主要概念虚拟内存的优势 内存管理内存碎片 内存分页页面置换算法TLB加速分页软件TLB管理针对大内存的页管理技术三个重要的缓存能力 内存保护总结 存储器的层次结构 对于存储器&#xff…

用Python打造精彩动画与视频.2.1 Python基础语法概述

2.1 Python基础语法概述 Python作为一门功能强大且易于学习的编程语言&#xff0c;其基础语法简单直观&#xff0c;非常适合初学者入门。这一节将带你了解Python的基本语法规则&#xff0c;为后续制作动画和视频打下坚实的基础。 1. 变量与数据类型 Python的变量不需要提前声…

OCC 创建倒角

目录 一、简介 二、示例 1、使用BRepFilletAPI_MakeFillet 创建倒角 2、使用BRepFilletAPI_MakeChamfer创建斜面倒角 三、总结 一、简介 倒角指的是把工件的棱角切削成一定斜面的加工。倒角是为了去除零件上因机加工产生的毛刺,也为了便于零件装配,一般在零件端部做出…

达梦数据库归档介绍

一、什么是归档 数据库归档是一种数据管理策略&#xff0c;它涉及将旧的、不经常访问的数据移动到一个单独的存储设备&#xff0c;以便在需要时可以检索&#xff0c;同时保持数据库的性能和效率。 归档的主要目标是为了释放数据库中的空间&#xff0c;以便更有效地利用高性能…

【C++高阶数据结构】红黑树:全面剖析与深度学习

目录 &#x1f680; 前言&#xff1a;红黑树与AVL树的比较一&#xff1a; &#x1f525; 红黑树的概念二&#xff1a; &#x1f525; 红黑树的性质 三&#xff1a; &#x1f525; 红黑树节点的定义和结构&#x1f680; 3.1 基本元素&#x1f680; 3.2 节点颜色&#x1f680; 3.…

MongoDB聚合操作详解

文章目录 聚合操作聚合管道管道&#xff08;Pipeline&#xff09;和阶段&#xff08;Stage&#xff09;常用的聚合阶段运算符准备数据集&#xff0c;执行脚本$project$match$count$group$unwind$limit$skip$sort$lookup聚合操作案例1聚合操作案例2 聚合优化执行顺序内存排序 整…

Hugo部署到Vercel踩大坑——全是XML文件?

问题描述 部署到Vercel全都是XML文件 Vercel是著名PAAS服务&#xff0c;相比于 Github Pages&#xff0c;其中国大陆可直接访问&#xff0c;因此尝试把Hugo站点发布到vercel中&#xff0c;部署后遇到问题&#xff0c;所有页面都为xml文件&#xff0c;如下所示&#xff1a; Ve…

AIGC-VDM -Video Diffusion Models论文解读

homepage&#xff1a;https://video-diffusion.github.io/ paper:https://arxiv.org/pdf/2204.03458 参考:https://zhuanlan.zhihu.com/p/585009571 视频生成方面的扩散模型 论文Video Diffusion Models精读&#xff0c;笔者会多多更新AIGC相关知识&#xff01;点个关注吧&…

SpringCloud Alibaba 微服务(二):Nacos

目录 前言 一、什么是Nacos&#xff1f; 二、Nacos的主要功能 服务发现与注册 配置管理 服务健康监控 集群模式 三、安装Nacos 下载Nacos 初始化Nacos 单机模式 集群模式 访问Nacos 四、服务注册 新建子工程 引入Nacos依赖 配置application.yml 创建启动类 …

内网穿透的应用-中文版个人知识库Trilium笔记本地安装结合内网穿透远程协作

文章目录 前言1. 安装docker与docker-compose2. 启动容器运行镜像3. 本地访问测试4.安装内网穿透5. 创建公网地址6. 创建固定公网地址 前言 今天和大家分享一款在G站获得了26K的强大的开源在线协作笔记软件&#xff0c;Trilium Notes的中文版如何在Linux环境使用docker本地部署…

Linux基础复习(五)

前言 本文介绍了Linux常用命令&#xff0c;接Linux基础复习&#xff08;四&#xff09; 一、常用命令 命令通配符 在Linux中&#xff0c;命令通配符&#xff08;也称为通配符模式或通配符表达式&#xff09;是用来匹配文件名或其他字符串的一种特殊字符。这些通配符可以帮助…

深入解析 GZIP 压缩传输:优化网络性能的利器

个人名片 🎓作者简介:java领域优质创作者 🌐个人主页:码农阿豪 📞工作室:新空间代码工作室(提供各种软件服务) 💌个人邮箱:[2435024119@qq.com] 📱个人微信:15279484656 🌐个人导航网站:www.forff.top 💡座右铭:总有人要赢。为什么不能是我呢? 专栏导…

访问控制列表(ACL)

文章目录 ACL原理与基本配置ACL分类ACL组成ACL规则的匹配与应用 ACL原理与基本配置 ACL(Access Control List&#xff0c;访问控制列表) 读取二层、三层、四层报文信息根据预先定义好的规则对报文进行过滤和分类实现网络访问控制、防止网络攻击和提高网络带宽利用率等目的提高…

力扣SQL50 上级经理已离职的公司员工 一题双解

Problem: 1978. 上级经理已离职的公司员工 Code -- 方法 1 -- select e1.employee_id -- from employees e1 -- left join employees e2 -- on e1.manager_id e2.employee_id -- where e1.salary < 30000 -- and e1.manager_id is not null -- and e2.employee_id is…

学鸿蒙开发好找工作吗?

学鸿蒙开发是一个非常有潜力的方向&#xff0c;因为鸿蒙系统是华为自主研发的操作系统&#xff0c;随着其在全球范围内的推广和应用&#xff0c;越来越多的企业和组织开始重视并采用这一系统。这使得鸿蒙开发者的市场需求正在持续增长&#xff0c;为鸿蒙开发者提供了更多的就业…

C# 设计倒计时器、串口助手开发

文章目录 1. 实现一个简单的倒计时器开始、暂停2. 串口助手开发 1. 实现一个简单的倒计时器开始、暂停 namespace Timer {public partial class Form1 : Form{int count;//用于定时器计数int time;//存储设定的定时值bool parse false;//控制暂停计时public Form1(){Initiali…

Qt Designer,仿作一个ui界面的练习(一):界面的基本布局

初学不要太复杂&#xff0c;先做一个结构简单的&#xff0c;大致规划一下功能分区&#xff0c;绘制草图&#xff1a; 最终的效果&#xff1a; 界面主要由顶边栏、侧边栏、内容区构成。顶边栏左边是logo&#xff0c;右边是时钟显示。侧边栏最上边是切换按钮&#xff0c;用以动画…

Qt中对象树机制的优点以及潜在的隐患

目录 一、什么是对象树 二、对象树的优点 三、对象树潜在的隐患 一、什么是对象树 Qt中的 QObject 会用对象树来组织管理自己&#xff0c;那什么是对象树? 这个概念非常好理解。因为 QObject 类就有一个私有变量 QList<QObject *>&#xff0c;专门存储这个类的子孙后…