【React】详解 Redux 状态管理

news2025/2/24 0:09:33

文章目录

    • 一、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.coloradmin.cn/o/1954424.html

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

相关文章

【Java算法专场】二分查找(下)

目录 山脉数组的峰顶索引 算法分析 算法步骤 算法代码 算法示例 寻找峰值 算法分析 算法步骤 算法代码 算法示例 寻找旋转排序数组中的最小值 算法分析 算法步骤 算法代码 算法示例 点名 算法分析 算法步骤 算法代码 算法示例 山脉数组的峰顶索引 …

生鲜云订单零售系统小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;商品分类管理&#xff0c;商品信息管理&#xff0c;订单评价管理&#xff0c;订单管理&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;商品信息&#…

DDOS攻击学习 - kali初学

文章目录 本地ssh配置nmap(网络连接的工具)nmap -sP IP地址nmap -p 1-65535 -A IP地址主机发现Ping扫描端口扫描时序扫描常用扫描方式指纹识别与探测全端口版本探测防火墙/IDS逃逸报文分段信息收集IP信息收集WHOIS查询数据库渗透测试MySQL列举数据库列举MySQL变量发起请求目录扫…

暑假第一周——网易云音乐仿写

iOS学习 前言发现&#xff1a;控件的堆叠我的&#xff1a;更换头像账号&#xff1a;切换夜间总结 前言 本周正式开始暑期学习&#xff0c;完成了网易云音乐的仿写。 发现&#xff1a;控件的堆叠 发现页面由一个无限轮播图&#xff0c;四个自定义cell完成。无限轮播图在之前已经…

【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第三篇 嵌入式Linux驱动开发篇-第五十九章 等待队列

i.MX8MM处理器采用了先进的14LPCFinFET工艺&#xff0c;提供更快的速度和更高的电源效率;四核Cortex-A53&#xff0c;单核Cortex-M4&#xff0c;多达五个内核 &#xff0c;主频高达1.8GHz&#xff0c;2G DDR4内存、8G EMMC存储。千兆工业级以太网、MIPI-DSI、USB HOST、WIFI/BT…

css 作业 2

文章目录 前言第四题第五题第六题第七题第八题第九题第十题&#xff08;子标签&#xff09; 前言 昨天写了前面三次作业&#xff0c;今天把剩下的七个作业写完 第四题 http://127.0.0.1:5500/index1.html&#xff0c;就用这个网址查看代码在网页的展示效果 代码评测过不了&…

【C语言】文件操作,文件读写详细介绍

目录 为什么要使用文件&#xff1f; 文件概念 1. 什么是文件&#xff1f; 2. 程序文件 3. 数据文件 4. 文件名 文件的使用 1. 文件指针 2. 文件的打开与关闭 文件的顺序读写 1. 顺序读写函数 2. scanf系列与printf系列 文件的随机读写 1. fseek 2. ftell 3. …

【C++】实验三

题目&#xff1a; 1、如何使用C来找出编码88表示的字符&#xff1f;指出至少两种方法。 思路&#xff1a;方法一定义一个字符型变量直接等于88&#xff0c;将其输出结果为编码88表示的字符&#xff1b;方法二使用整形变量来存储88&#xff0c;输出时将其强制转换成字符型。 …

GD32 MCU如何将烧录口配置为GPIO使用?

如果大家在进行GD32 MCU开发时发现GPIO引脚使用不足&#xff0c;可以尝试将烧录口配置为GPIO使用&#xff0c;这样就可以多出几个引脚使用&#xff0c;但使用的时候如何配置以及有哪些注意事项&#xff0c;本视频将会为大家进行解答。 GD32 MCU存在两种GPIO备用功能的配置&…

数字陷波器的设计和仿真(Matlab+C)

目录 一、数字陷波器的模型 二、Matlab仿真 1. 示例1 2. 示例2 三、C语言仿真 1. 由系统函数计算差分方程 2. 示例代码 一、数字陷波器的模型 二、Matlab仿真 1. 示例1 clear clc f0=100;%滤掉的100Hz fs=1000;%大于两倍的信号最高频率 r=0.9; w0=2*pi*f0/fs;%转换到…

【深度学习】语音合成,TTS,fish-speech

官方项目地址&#xff1a;https://github.com/fishaudio/fish-speech git clone https://github.com/fishaudio/fish-speech.gitdocker run -it --gpus device3 -v /ssd/xiedong/tts:/ssd/xiedong/tts --net host --shm-size 16G kevinchina/deeplearning:pytorch2.3.0-cuda12.…

玩转CSS:用ul li +JS 模拟select,避坑浏览器不兼容。

玩转CSS&#xff1a;用ul li JS 模拟select&#xff0c;避坑浏览器不兼容。 在前端的工作中&#xff0c;经常会遇到 selcet控件&#xff0c;但我们用css来写它的样式时候&#xff0c;总是不那么令人满意&#xff0c;各种浏览器不兼容啊有没有&#xff1f; 那么&#xff0c;我…

Datawhale AI 夏令营——AI+逻辑推理——Task1

# Datawhale AI 夏令营 夏令营手册&#xff1a;从零入门 AI 逻辑推理 比赛&#xff1a;第二届世界科学智能大赛逻辑推理赛道&#xff1a;复杂推理能力评估 代码运行平台&#xff1a;魔搭社区 比赛任务 本次比赛提供基于自然语言的逻辑推理问题&#xff0c;涉及多样的场景&…

27K star!有没有显卡都能搞,快速基于LLM构建本地智能知识库

觉得搞一个AI的智能问答知识库很难吗&#xff1f;那是你没有找对方向和工具&#xff0c; 今天我们分享一个开源项目&#xff0c;帮助你快速构建基于Langchain 和LLM 的本地知识库问答&#xff0c;在GitHub已经获得27K star&#xff0c;它就是&#xff1a;Langchain-Chatchat L…

在Spring项目中使用Maven和BCrypt来实现修改密码功能

简介 在数字时代&#xff0c;信息安全的重要性不言而喻&#xff0c;尤其当涉及到个人隐私和账户安全时。每天&#xff0c;无数的用户登录各种在线服务&#xff0c;从社交媒体到银行账户&#xff0c;再到电子邮件和云存储服务。这些服务的背后&#xff0c;是复杂的系统架构&am…

进程间关系

目录 亲缘关系 进程组关系 会话关系 孤儿态进程 亲缘关系 亲缘关系主要体现于父子进程&#xff0c;子进程父进程创建&#xff0c;代码继承于父进程&#xff0c;父进程负责回收&#xff0c;子进程诞生至结束父进程全程参与&#xff0c;这种称为强亲缘关系。 系统开机后&…

企业级数据分析平台合集介绍

企业发展离不开数据分析&#xff0c;数据分析推动着企业运营、决策和战略规划。它正逐步深入到各行各业的核心业务流程中&#xff0c;从传统的金融、零售、制造业扩展到医疗健康、教育、能源等更多领域。企业正通过数据分析平台实现数据资源的最大化利用&#xff0c;推动业务与…

wireshark--流量分析利器

&#x1f3bc;个人主页&#xff1a;金灰 &#x1f60e;作者简介:一名简单的大一学生;易编橙终身成长社群的嘉宾.✨ 专注网络空间安全服务,期待与您的交流分享~ 感谢您的点赞、关注、评论、收藏、是对我最大的认可和支持&#xff01;❤️ &#x1f34a;易编橙终身成长社群&#…

基于微信小程序的课堂考勤系统的设计与实现(论文+源码)_kaic

基于微信小程序的课堂考勤系统的设计与实现 摘 要 在高校教育普及的今天&#xff0c;学生人数日益增多&#xff0c;为保证课堂质量&#xff0c;教师多要在课前进行考勤。因此本设计提出基于微信小程序的课堂考勤系统&#xff0c;增加了定位功能&#xff0c;避免了“假打卡”…

探索大型语言模型LLama 2:原理揭秘与代码实践

一、引言 1.1 大型语言模型的重要性 大型语言模型作为人工智能领域的重要研究方向&#xff0c;近年来取得了显著的成果。这些模型在自然语言处理、机器翻译、对话系统、文本生成等领域展现了强大的能力&#xff0c;为人类带来了诸多便利。大型语言模型的出现&#xff0c;使得…