React 中使用 Redux Toolkit 状态管理

在现代 React 应用程序中,状态管理是一个至关重要的部分。使用 Redux Toolkit 可以简化 Redux 的配置和管理。本文将通过三个文件的示例,详细讲解如何使用 Redux Toolkit 创建和管理一个简单的计数器状态,并通过类比源 store 和根 store 的概念,加以更好地理解。

一、什么是源 Store 和根 Store?

这里只是自己觉得这样定义会更好理解一些,实际并没有这样的概念

源 Store

源 store 是模块化的状态管理单元,负责特定功能的状态和操作。使用 createSlice 创建的 slice 就是源 store。

类比:可以想象成一个专注于特定产品的车间,例如一个玩具制造车间。它只负责制造特定类型的玩具(如计数器的状态管理),并且有自己的一套操作流程(增、减、重置)。

根 Store

根 store 是整个应用的状态管理中心,使用 configureStore 组合多个源 store。它负责将所有的状态和逻辑集中起来,提供给整个应用使用。

类比:可以想象成一个大型工厂,里面有多个车间(源 store)。有负责制造玩具的,有负责制造家具的。。。这个工厂负责管理和协调各个车间的生产,并且能够根据需求调整生产线(即添加或修改源 store)。

二、创建 Counter Store

2.1 定义源 Store

在一个新的文件 counterSlice.js 中,我们将创建计数器的 slice:

//  store/modules/xxx.js

import { createSlice } from '@reduxjs/toolkit';

// 创建一个 slice
const counterSlice = createSlice({
  name: 'counter',  // 定义 slice 的名称
  initialState: {   // 初始化状态
    count: 0,       // 需要被全局维护的数据
  },
  reducers: {       // 定义修改状态的方法
    increment(state) {
      state.count += 1;  // 增加计数
    },
    decrement(state) {
      state.count -= 1;  // 减少计数
    },
    reset(state) {
      state.count = 0;    // 重置计数
    },
  },
});

// 导出 action 对象
export const { increment, decrement, reset } = counterSlice.actions;

// 导出 reducer 函数
export const counterReducer = counterSlice.reducer;

在这个例子中,counterSlice 就是我们的源 store,它初始化了一个 count 状态,并提供了三个 reducers 来修改这个状态。

三、组合 Store(根)

在另一个文件 store.js 中,我们将使用 configureStore 来组合根 store,并把 counterReducer 传入:

// store/index.js

import { configureStore } from '@reduxjs/toolkit';
import { counterReducer } from './counterSlice';

// 创建根 store
const store = configureStore({
  reducer: {
    counter: counterReducer,  // 将源 reducer 组合到根 store 中
  },
});

export default store;

这里,store 就是我们的根 store,它可以容纳多个源 store(在本例中只有 counter),并将它们组合在一起进行集中管理。

根store中可以定义多个源store,这里只示例一个

四、连接 React 和 Redux

我们目前只是使用了源store中的reducer函数来组合根store,还有定义导出的源store中的action对象并没有使用

现在我们已经定义了 store,但还需要将其链接到我们的 React 应用中。我们将使用 react-redux 中的 Provider 组件来实现这一点。

4.1 绑定 Store(为组件注入store)

index.jsApp.js 中,我们将 Provider 组件包裹住我们的应用:

// 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')
);

4.2 使用 Store 中的数据(调用触发)

在我们的组件中,使用 useSelector 钩子来访问 store 中的状态,并使用 useDispatch 钩子来触发 action。

// App.js

import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { increment, decrement, reset } from './counterSlice';

const Counter = () => {
  const count = useSelector(state => state.counter.count);  // 获取状态
  const dispatch = useDispatch();  // 获取 dispatch 函数

  return (
    <div>
      <h1>Count: {count}</h1>
      <button onClick={() => dispatch(increment())}>Increment</button>
      <button onClick={() => dispatch(decrement())}>Decrement</button>
      <button onClick={() => dispatch(reset())}>Reset</button>
    </div>
  );
};

export default Counter;

在这个组件中,我们通过 useSelector 获取 count 状态,并通过 useDispatch 触发 incrementdecrementreset 这三个 action。

总结

通过以上步骤,我们成功使用 Redux Toolkit 创建了一个简单的计数器应用。整个过程包括:

  1. 定义源 store(创建 slice)。
  2. 将源 store 组合到根 store 中。
  3. 通过 Provider 注入 store 到 React 应用中。
  4. 使用 useSelectoruseDispatch 连接组件与 store,实现状态管理。

扩展:

1.action传参:

  1. 对源store的reducer中的action对象多传递一个action参数,这个参数就是我们触发方法传递的数据了
  2. 通过action.payload拿到数据
    addToNum(state, action) {
        state.count = action.payload
    }

调用触发

dispatch(addToNum(20))

 2.异步操作获取数据

(1).在源store外面定义一个异步函数并暴露出去,异步函数中调用dispatch()

dispatch中传递源store中reducer中的action对象

// channelStore.js (源)

// 解构出action对象
const {setChannel} = channelStore.actions

// 封装函数
const fetchChannelList = ()=>{
    return async(dispatch) =>{
        const res = await.get(url) // url是请求后端的地址
        // setChannel是源store在reducer中定义的action对象
        dispatch(setChannel(res.data.channels))
    }
}

注意,因为给action对象传递参数了,所以参考上面的action传参,需要源store中的action对象多定义一个action形参来接收数据

// channelStore.js (源)

reducers:{
        setChannels(state,action){
        state.channelList = action.payload
    }
}

(2).在需要的地方调用:

// App.js

const dispatch = useDispatch()
useEffect(()=>{
    dispatch(fetchChannelList())
},[dispatch]

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

3、liunx系统网络配置

一、liunx网络配置 Linux服务器网卡默认配置文件在/etc/sysconfig/network-scripts/下&#xff0c;命名的名称一般为:ifcfg-eth0 ifcfg-eth1 &#xff0c;eth0表示第一块网卡&#xff0c;eth1表示第二块网卡&#xff0c;依次类推&#xff0c;例如DELL R720标配有4块千兆网卡&am…

【零售和消费品&存货】快递包裹条形码与二维码识别系统源码&数据集全套:改进yolo11-RFCBAMConv

改进yolo11-RVB等200全套创新点大全&#xff1a;快递包裹条形码与二维码识别系统源码&#xff06;数据集全套 1.图片效果展示 项目来源 人工智能促进会 2024.11.01 注意&#xff1a;由于项目一直在更新迭代&#xff0c;上面“1.图片效果展示”和“2.视频效果展示”展示的系统…

牛客网最新Java高频面试题汇总(2024最新含答案)

作为一名优秀的程序员&#xff0c;技术面试都是不可避免的一个环节&#xff0c;一般技术面试官都会通过自己的方式去考察程序员的技术功底与基础理论知识。 如果你参加过一些大厂面试&#xff0c;肯定会遇到一些这样的问题&#xff1a; 1、看你项目都用的框架&#xff0c;熟悉…

电科金仓(人大金仓)更新授权文件(致命错误: XX000: License file expired.)

问题:电科金仓(人大金仓)数据库链接异常,重启失败,查看日志如下: 致命错误: XX000: License file expired. 位置: PostmasterMain, postmaster.c:725 解决方法: 一、下载授权文件 根据安装版本在官网下载授权文件(电科金仓-成为世界卓越的数据库产品与服务提供商)…

Hadoop期末复习(完整版)

前言&#xff08;全部为语雀导出&#xff0c;个人所写&#xff0c;仅用于学习&#xff01;&#xff01;&#xff01;&#xff01;&#xff09; 复习之前我们要有目的性&#xff0c;明确考什么&#xff0c;不考什么。 对于hadoop来说&#xff0c;首先理论方面是跑不掉的&#x…

河北冠益荣信科技公司洞庭变电站工程低压备自投装置的应用

摘 要&#xff1a;随着电力需求增长&#xff0c;供电可靠性变得至关重要&#xff0c;许多系统已有多回路供电。备用电源自动投入装置能提升供电可靠性&#xff0c;它能在主电源故障时迅速切换到备用电源。本文介绍的AM5-DB低压备自投装置&#xff0c;为洞庭变电站提供多种供电方…

Spring Boot:打造动态定时任务,开启灵活调度之旅

一、描述 在 Spring Boot 中设置动态定时任务是一种非常实用的功能&#xff0c;可以根据实际需求在运行时动态地调整定时任务的执行时间、频率等参数。以下是对 Spring Boot 设置动态定时任务的简单介绍&#xff1a; 1、传统定时任务的局限性 在传统的 Spring Boot 定时任务…

Lua 从基础入门到精通(非常详细)

目录 什么是 Lua&#xff1f; Lua 环境安装 Lua基本语法 注释 数据类型 nil&#xff08;空&#xff09; Boolean number&#xff08;数字&#xff09; string&#xff08;字符串&#xff09; function&#xff08;函数&#xff09; userdata thread table&#xff…

PostgreSQL 到 PostgreSQL 数据迁移同步

简述 PostgreSQL 是一个历史悠久且广泛使用的数据库&#xff0c;不仅具备标准的关系型数据库能力&#xff0c;还具有相当不错的复杂 SQL 执行能力。用户常常会将 PostgreSQL 应用于在线事务型业务&#xff0c;以及部分数据分析工作&#xff0c;所以 PostgreSQL 到 PostgreSQL …

GESP4级考试语法知识(捕捉异常)

参考程序代码&#xff1a; #include <iostream> using namespace std;double divide(double a, double b) {if (b 0) {throw "Division by zero error"; // 抛出异常}return a / b; }int main() {double num1, num2;cout << "Enter two numbers:…

新老项目不同node版本,使用nvm控制node版本切换(mac、window)

window系统电脑的链接&#xff1a;https://blog.csdn.net/qq_40269801/article/details/136450961 以下是mac版本的操作方式&#xff1a; 1、打开终端 克隆 NVM 仓库&#xff1a; git clone https://github.com/nvm-sh/nvm.git ~/.nvm 2、运行安装脚本&#xff1a; cd ~/.n…

HTTP与HTTPS协议

HTTP协议&#xff0c;即超文本传输协议&#xff08;HyperText Transfer Protocol&#xff09;&#xff0c;是互联网中一种用于在Web浏览器与Web服务器之间传输数据的应用层协议。它的核心理念是提供一种简单、灵活的方式来请求和响应信息&#xff0c;是现代万维网的基础。 1. 什…

R语言机器学习与临床预测模型79--机器学习总览

R小盐准备介绍R语言机器学习与预测模型的学习笔记 你想要的R语言学习资料都在这里&#xff0c; 快来收藏关注【科研私家菜】 01 机器学习分类 机器学习模型主要分为有监督、无监督和强化学习方法。 监督学习 监督学习是教师向学生提供关于他们在考试中是否表现良好的反馈。其中…

Diving into the STM32 HAL-----HAL_GPIO

1、怎么看待外设&#xff1a; 从总线连接的角度看&#xff0c;外设和Core、DMA通过总线交换数据&#xff0c;正所谓要想富先修路。要注意&#xff0c;这些总线中的每一个都连接到不同的时钟源&#xff0c;这些时钟源决定了连接到该总线的外设操作的最大速度。 从内存分配的角度…

FlinkCDC-MYSQL批量写入

一、运行环境 &#xff08;1&#xff09;Flink&#xff1a;1.17.2 &#xff08;2&#xff09;Scala&#xff1a;2.12.20 &#xff08;3&#xff09;Mysql&#xff1a;5.7.43 ##开启binlog 二、代码示例 思路&#xff1a;通过滚动窗口收集一批数据推给sink消费。binlog日志对…

集合(数组、链表、map)

目录 Collection包结构 和collections区别 List 数组和arrayList 区别 数组下标为什么从0开始&#xff1f; ArrayList 动态数组 LinkedList双向链表增删快 增删快 链表 单链表和双链表区别 Arraylist VS LinkedList 区别 数组和List之间转换 ArrayList 、LinkedList…

多线程和线程同步基础篇学习笔记(Linux)

大丙老师教学视频&#xff1a;10-线程死锁_哔哩哔哩_bilibili 目录 大丙老师教学视频&#xff1a;10-线程死锁_哔哩哔哩_bilibili 线程概念 为什么要有线程 线程和进程的区别 在处理多任务的时候为什么线程数量不是越多越好? Linux提供的线程API 主要接口 线程创建 pth…

希望十一月对我好一点:C++之多态(2)--多态的原理(部分)

多态的原理 虚函数表指针 下⾯编译为32位程序的运⾏结果是什么&#xff08;&#xff09; A. 编译报错 B.运⾏报错C.8 D.12 class Base{public:virtual void Func1(){cout << "Func1()" << endl;}protected:int _b 1;char _ch x;};int main(){Base b…

Java: 遍历 Map

Java: 遍历 Map package animals;import java.util.HashMap; import java.util.Iterator; import java.util.Map;/*** Description :** author : HMF* Date : Created in 15:33 2024/11/1* version :*/ public class Test002 {public static void main(String[] args){Map<S…

基于vue+neo4j 的中药方剂知识图谱可视化系统

前言 历时一周时间&#xff0c;中药大数据R02系统中药开发完毕&#xff0c;该系统通过scrapy工程获取中药数据&#xff0c;使用python pandas预处理数据生成知识图谱和其他相关数据&#xff0c;利用vuespringbootneo4jmysql 开发系统&#xff0c;具体功能请看本文介绍。 简要…