详细介绍 React 中如何使用 redux

在使用之前要先了解它的配套插件:

在React中使用redux,官方要求安装其他插件 Redux Toolkit 和 react-redux

  1. Redux Toolkit:它是一个官方推荐的工具集,旨在简化 Redux 的使用和管理。Redux Toolkit 提供了一些提高开发效率的工具和功能,如 createSlice 和 configureStore,使得编写和组织 Redux 代码更加简单。使用 Redux Toolkit,您可以更快地编写 Redux 代码,同时还能获得一些性能优化和开发便利。

    安装 Redux Toolkit:

npm install @reduxjs/toolkit

  1. react-redux:它是 Redux 官方提供的与 React 集成的库。它提供了 Provider 组件来将 Redux store 注入到整个 React 应用中,以及 useDispatch 和 useSelector 这些方便的钩子函数,用于在 React 组件中使用 Redux 的 dispatch 和选择器功能。

    安装 react-redux:

npm install react-redux

安装这两个插件后,您就可以在 React 应用中使用 Redux 并使用 Redux Toolkit 进行更简洁、高效的编码,同时通过 react-redux 方便地与 React 进行集成。

创建一个新的react 文件,且安装了两个插件后,调整目录结构

image.png

开始使用:

第一步:初始化 state,定义修改状态的方法,解构出来 actionCreater函数,获取 reducer

reducer 用于定义如何更新应用的状态。它接收两个参数:当前的状态(state)和即将执行的 action,并返回一个新的状态。

counterStore.js

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

const counterStore = createSlice({
  name: "counter",
  
  // 初始化 state
  initialState: {
    count: 0,
  },
  
  // 修改状态的方法 同步方法,可以直接修改值
  reducers: {
    addCount(state) {
      state.count++;
    },
    decreaseCount(state) {
      state.count--;
    },
  },
});

// 解构出来 actionCreater函数
const { addCount, decreaseCount } = counterStore.actions;
// 获取 reducer
const reducer = counterStore.reducer;
// 按需导出
export { addCount, decreaseCount };
// 默认导出
export default reducer;

第二步:在出口文件中导出 redux

src\store\index.js

// 出口文件
import { configureStore } from "@reduxjs/toolkit";
// 导入子模块
import counterStore from "./modules/counterStore";

const store = configureStore({
  reducer: {
    counter: counterStore,
  },
});

// 导出
export default store;

第三步:配置redux 中的数据全局可用

src\index.js

import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
// Redux
import store from "./store";
import { Provider } from "react-redux";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <React.StrictMode>
    {/* 全局可用 */}
    <Provider store={store}>
      <App />
    </Provider>
  </React.StrictMode>
);

reportWebVitals();

第四步:使用

useDispatch:它简化了在函数组件中使用 dispatch 函数的过程,无需手动从 store 中获取 dispatch 函数。

useSelector:它允许组件从 Redux store 中选择(select)所需的状态。通过它可以订阅 Redux store 的状态,以便在组件中获取所需的数据。

App.js

import "./App.css";
import { useDispatch, useSelector } from "react-redux";
// 获取
import { addCount, decreaseCount } from "./store/modules/counterStore";

function App() {
  // 得到 Redux 中的数据
  const { count } = useSelector((state) => state.counter);
  // 处理数据的函数
  const dispatch = useDispatch();
  return (
    <div className="App">
      <button onClick={() => dispatch(addCount())}>+</button>
      <p>{count}</p>
      <button onClick={() => dispatch(decreaseCount())}>-</button>
    </div>
  );
}

export default App;

携带参数

 // 接收传参
    addTonum(state, action) {
      // action.payload 可以获取到传入的参数
      state.count = action.payload;
    },
import { createSlice } from "@reduxjs/toolkit";

const counterStore = createSlice({
  name: "counter",
  // 初始化 state
  initialState: {
    count: 0,
  },
  // 修改状态的方法 同步方法,可以直接修改值
  reducers: {
    addCount(state) {
      state.count++;
    },
    decreaseCount(state) {
      state.count--;
    },
    // 接收传参
    addTonum(state, action) {
      // action.payload 可以获取到传入的参数
      state.count = action.payload;
    },
  },
});

// 解构出来 actionCreater函数
const { addCount, decreaseCount, addTonum } = counterStore.actions;
// 获取 reducer
// 用于定义如何更新应用的状态。它接收两个参数:当前的状态(state)和即将执行的 action,并返回一个新的状态。
const reducer = counterStore.reducer;

// 按需导出
export { addCount, decreaseCount, addTonum };
// 默认导出
export default reducer;

App.js

      <button onClick={() => dispatch(addTonum(10))}>+10</button>
      <button onClick={() => dispatch(addTonum(20))}>+20</button>

异步请求部分

异步封装的实现

1.创建store的写法保持不变,配置好同步修改状态的方法

2.单独封装一个函数,在函数内部return一个新函数,在新函数中

2.1封装异步请求获取数据

2.2调用同步actionCreater传入异步数据生成一个action对象,并使用dispatch提交

3.组件中dispatch的写法保持不变

src\store\modules\channelStore.js

// 异步封装的实现
import { createSlice } from "@reduxjs/toolkit";
import axios from "axios";

const channelStore = createSlice({
  name: "channel",
  
  // 初始值
  initialState: {
    channelList: [],
  },
  reducers: {
    setChannels(state, action) {
      state.channelList = action.payload;
    },
  },
});

  
// 异步请求部分
// http://geek.itheima.net/v1_0/channels
const { setChannels } = channelStore.actions;

const fetchChannlList = () => {
  return async (dispatch) => {
    const res = await axios.get("http://geek.itheima.net/v1_0/channels");
    dispatch(setChannels(res.data.data.channels));
  };
};

export { fetchChannlList };

const reducer = channelStore.reducer;
export default reducer;

出口文件

src\store\index.js

// 出口文件
import { configureStore } from "@reduxjs/toolkit";
// 导入子模块
import counterStore from "./modules/counterStore";
import channelStore from "./modules/channelStore";

const store = configureStore({
  reducer: {
    counter: counterStore,
    channel: channelStore,
  },
});

// 导出
export default store;

使用

App.js

import "./App.css";
import { useEffect } from "react";

import { useDispatch, useSelector } from "react-redux";
// 获取
import {
  addCount,
  decreaseCount,
  addTonum,
} from "./store/modules/counterStore";
import { fetchChannlList } from "./store/modules/channelStore";

function App() {
  // 得到 Redux 中的数据
  const { count } = useSelector((state) => state.counter);
  const { channelList } = useSelector((state) => state.channel);

  // 处理数据的函数
  const dispatch = useDispatch();
  // 挂载渲染
  useEffect(() => {
    dispatch(fetchChannlList());
  }, [dispatch]);
  return (
    <div className="App">
      <button onClick={() => dispatch(addCount())}>+</button>
      <p>{count}</p>
      <button onClick={() => dispatch(decreaseCount())}>-</button>
      <hr />
      {/* redux 传入参数 */}
      <button onClick={() => dispatch(addTonum(10))}>+10</button>
      <button onClick={() => dispatch(addTonum(20))}>+20</button>
      <hr />
      {/* 异步 */}
      <ul>
        {channelList.map((item) => (
          <li key={item.id}>{item.name}</li>
        ))}
      </ul>
    </div>
  );
}

export default App;

浏览器插件,管理 redux

Redux DevTools

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

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

相关文章

GO语言日志切割 + 记录调用源

准备工作 日志记录对程序排查问题比较关键&#xff0c;记录下GO中日志选择&#xff0c;从以下出发点考虑&#xff1a; 日志文件能自动切割&#xff0c;以免过大能记录从哪个文件哪行代码调用的&#xff0c;方便排查问题配置简单明了库文件使用人数较多&#xff0c;稳定 经过一段…

ChatIE:通过多轮问答问题实现实命名实体识别和关系事件的零样本信息抽取,并在NYT11-HRL等数据集上超过了全监督模型

项目设计集合&#xff08;人工智能方向&#xff09;&#xff1a;助力新人快速实战掌握技能、自主完成项目设计升级&#xff0c;提升自身的硬实力&#xff08;不仅限NLP、知识图谱、计算机视觉等领域&#xff09;&#xff1a;汇总有意义的项目设计集合&#xff0c;助力新人快速实…

python读取json文件

import json# 文件路径(同目录文件名即可,不同目录需要绝对路径) path 1.json# 读取JSON文件 with open(path, r, encodingutf-8) as file:data json.load(file)#data为字典 print(data) print(type(data))

文件上传

js绕过 打开网页尝试上传一句话木马&#xff0c;发现只能上传图片文件 审计源代码&#xff0c;发现使用一个checkfile函数js对文件类型进行了屏蔽 于是我们修改网页代码&#xff0c;去除返回值的检查函数 checkFile() 上传成功&#xff0c;使用蚁剑连接 连接成功 .htaccess绕…

element-ui使用动态渲染下拉选择框el-select已经选择的下拉框的值不可以重复选择让其disabled

调接口拿到下拉框数据的数据的时候将其disabled全为true 但是如果编辑的时候就需要与详情接口对比&#xff0c;如果有id一致就将disabled为true if (res.code 0) {if (this.dialogtitle "新增合同") {res.data.map((v) > {v.nameUnitVoList.forEach((item) >…

小程序新渲染引擎 Skyline 发布正式版

为了进一步提升小程序的渲染性能和体验&#xff0c;我们推出了一套新渲染引擎 Skyline&#xff0c;现在&#xff0c;跟随着基础库 3.0.0 发布 Skyline 正式版。 我们知道&#xff0c;小程序一直用 WebView 来渲染界面&#xff0c;因其有不错的兼容性和丰富的特性&#xff0c;且…

lc209.长度最小的子数组

暴力破解&#xff1a;二次for循环遍历num[i]...num[j]&#xff0c;记录满足条件的最小长度 前缀和二分&#xff1a;前缀和降低计算num[i]...num[j]的时间复杂度 对前缀和数组中的每个数进行遍历&#xff0c;找到距离这个数满足条件的最小长度 前缀和数组单调递增&#xff0c;此…

最小时间差(力扣)排序 + 思维 JAVA

给定一个 24 小时制&#xff08;小时:分钟 “HH:MM”&#xff09;的时间列表&#xff0c;找出列表中任意两个时间的最小时间差并以分钟数表示。 示例 1&#xff1a; 输入&#xff1a;timePoints [“23:59”,“00:00”] 输出&#xff1a;1 示例 2&#xff1a; 输入&#xff1a;…

支持向量机(iris)

代码&#xff1a; import pandas as pd from sklearn.preprocessing import StandardScaler from sklearn import svm import numpy as np# 定义每一列的属性 colnames [sepal-length, sepal-width, petal-length, petal-width, class] # 读取数据 iris pd.read_csv(data\\i…

[自然语言处理] 自然语言处理库spaCy使用指北

spaCy是一个基于Python编写的开源自然语言处理库。基于自然处理领域的最新研究&#xff0c;spaCy提供了一系列高效且易用的工具&#xff0c;用于文本预处理、文本解析、命名实体识别、词性标注、句法分析和文本分类等任务。 spaCy的官方仓库地址为&#xff1a;spaCy-github。本…

信号的学习笔记二

文章目录 信号捕捉signal信号捕捉sigaction信号集未决信号集和阻塞信号集的工作过程 ![在这里插入图片描述](https://img-blog.csdnimg.cn/b896346af6f1462089779e513a7e237b.png)信号集相关函数sigemptysetsigfillsetsigaddsetsigdelsetsigismember应用 以下函数设置内核信号集…

八股总结(八)SSM框架体系

文章目录 Spring基础1、Spring、SpringMVC、Mybatis与SpringBoot的区别2、Spring中常用的注解及作用 Spring IoC 、 DI、Bean3、Spring IoC是什么&#xff0c;有什么好处&#xff0c;Spring中是怎么实现的&#xff1f;4、Bean相关5、Component 和 Bean 的区别是什么&#xff1f…

Java-简单认识类和对象

一、初步认识面向对象 1.1 什么是面向对象 Java是一门纯面向对象的语言(Object Oriented Program&#xff0c;简称OOP)&#xff0c;在面向对象的世界里&#xff0c;一切皆为对象。面向对象是解决问题的一种思想&#xff0c;主要依靠对象之间的交互完成一件事情。用面向对象的思…

系统架构设计师 10:软件架构的演化和维护

一、软件架构演化 如果软件架构的定义是 SA{components, connectors, constraints}&#xff0c;也就是说&#xff0c;软件架构包括组件、连接件和约束三大要素&#xff0c;这类软件架构演化主要关注的就是组件、连接件和约束的添加、修改与删除等。 二、面向对象软件架构演化…

使用Appuploader工具将IPA上传到App Store的最新流程和步骤

​ 苹果官方提供的工具xcode上架ipa非常复杂麻烦。用appuploader 可以在 mac 和windows 上制作管理 证书 &#xff0c;无需钥匙串工具 条件&#xff1a;1.以Windows为例&#xff0c;创建app打包ios需要的证书和描述文件 2.准备好一个苹果开发者账号&#xff08;如果没有到苹果…

C#实现读写CSV文件的方法详解

目录 CSV文件标准 文件示例RFC 4180简化标准读写CSV文件 使用CsvHelper使用自定义方法总结 项目中经常遇到CSV文件的读写需求&#xff0c;其中的难点主要是CSV文件的解析。本文会介绍CsvHelper、TextFieldParser、正则表达式三种解析CSV文件的方法&#xff0c;顺带也会介绍一…

QGIS3.28的二次开发一:编译工程

环境&#xff1a;VS2019OSGeo4WCMake_3.26Cygwin64QGIS_3.28 注意&#xff1a;一定要按照步骤顺序来&#xff01; 一、配置环境 &#xff08;一&#xff09;VS2019 VS2019下载链接https://my.visualstudio.com/Downloads?qvisual%20studio%202019&wt.mc_ido~msft~vsco…

Java面向对象编程实战详解(图书管理系统示例)

文章目录 面向编程概念图书管理系统示例需求分析设计阶段编码实现创建目录结构Book类的编码BookList类的编码User类的编码AdminUser类的编码NormalUser类的编码启动类的编写具体的操作实现IOperation接口新增图书的实现借阅图书的实现删除图书的实现显示图书的实现查找图书的实…

1.netty介绍

1.介绍 是JBOSS通过的java开源框架是异步的,基于事件驱动(点击一个按钮调用某个函数)的网络应用框架,高性能高可靠的网络IO程序基于TCP,面向客户端高并发应用/点对点大量数据持续传输的应用是NIO框架 (IO的一层层封装) TCP/IP->javaIO和网络编程–>NIO—>Netty 2.应用…

一文讲清楚地图地理坐标系

前言 我最近在做一个和地图有关的项目&#xff0c;这里本人地图采用的是mapbox&#xff0c;其中涉及一个功能需要根据用户输入的地点直接定位到地图上的对应的位置&#xff0c;本人开始想的是直接调用百度的接口根据地名直接获取坐标&#xff0c;发现在地图上的位置有偏移不够…