react 状态管理

embedded/2024/10/4 12:59:15/

Redux

ReduxReact中常用的状态管理组件,类似于Vue中的Pinia(Vuex),可以独立于框架运行

作用: 通过集中管理的方式管理应用的状态

配套工具

react中使用redux,官方要求按照两个插件,Redux Toolkitreact-redux

Redux Toolkit 是官方推荐编写Redux逻辑的方式,是一套工具的集合集,简化书写方式

react-redux 用来连接reduxreact组件的中间件

npm i @reduxjs/toolkit react-redux

store目录结构设计

  • 通常集中状态管理的部分都会单独创建一个store目录
  • 应用通常会有多个子store模块,所以创建一个modules目录,在内部编写业务分类的子store
  • store中的入口文件index.js的作用是组合modules中所有的子模块,并导出store

在这里插入图片描述

使用

counterStore.js

import { createSlice } from "@reduxjs/toolkit";const counterStore = createSlice({// 名称name: "counter",// 初始化状态initialState:{count:0},//修改数据的同步方法reducers:{add(store){store.count++},sub(store){store.count--}}
})
// 结构出action对象中的函数
const {add,sub} = counterStore.actions
// reducer函数
const currentReducer = counterStore.reducer
// 导出
export default currentReducer
export {add,sub}

index.js

import { configureStore } from "@reduxjs/toolkit";import counterReducer from "./modules/counterStore";// 创建根store组合子模块
const store = configureStore({reducer:{counter:counterReducer}
})export default store;

为react注入store
react-redux负责把ReduxReact连接起来,内置Provider组件,通过store参数把创建好的store实例注入到应用中。

main.jsx 项目的入口文件

import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import App from './App.jsx'
import './index.css'
import store from './store'
import { Provider } from 'react-redux'createRoot(document.getElementById('root')).render(<StrictMode><Provider store={store}><App /></Provider></StrictMode>,
)

在组件中使用

react组件中使用store中的数据,需要用到一个钩子函数useSelector,它的作用是把store中的数据映射到组件中

function App() {const counterReducer = useSelector(state => state.counter);return (<div><div>当前值:{counterReducer.count}</div></div>);
}

在这里插入图片描述
在这里插入图片描述
React组件中修改store中的数据需要借助另外一个hook函数——useDispatch,它的作用是生成提交action对象的dispatch函数

import './App.css'
import { useSelector,useDispatch } from 'react-redux';// 导入创建的action对象的方法
import { add, sub } from './store/modules/counterStore';
function App() {const counterReducer = useSelector(state => state.counter);// 获取dispatch函数const dispatch = useDispatch();return (<div><div>当前值:{counterReducer.count}</div>{/* 调用 */}<button onClick={() => dispatch(add())}>加一</button><button onClick={() => dispatch(sub())}>减一</button></div>);
}

在这里插入图片描述

提交action传参

reducers的同步修改方法中添加action对象参数,在调用ationCreater的时候传递参数,参数会被传递到action对象的payload属性上

import { createSlice } from "@reduxjs/toolkit";const counterStore = createSlice({// 名称name: "counter",// 初始化状态initialState:{count:0},//修改数据的同步方法reducers:{add(store){store.count++},sub(store){store.count--},addNum(store,action){store.count+= action.payload}}
})
// 结构出action对象中的函数
const {add,sub,addNum} = counterStore.actions
// reducer函数
const currentReducer = counterStore.reducer
// 导出
export default currentReducer
export {add,sub,addNum}
在这里插入代码片
import './App.css'
import { useSelector,useDispatch } from 'react-redux';// 导入创建的action对象的方法
import { add, sub,addNum } from './store/modules/counterStore';
function App() {const counterReducer = useSelector(state => state.counter);// 获取dispatch函数const dispatch = useDispatch();return (<div><div>当前值:{counterReducer.count}</div>{/* 调用 */}<button onClick={() => dispatch(add())}>加一</button><button onClick={() => dispatch(sub())}>减一</button>{/* 加三 */}<button onClick={() => dispatch(addNum(3))}>加三</button></div>);
}

在这里插入图片描述

异步操作

  • 创建store的方式不变,配置好同步修改状态的方法
  • 单独封装一个函数,在函数内部return一个新函数,在新函数中
    • 封装异步请求获取数据
    • 调用同步actionCreate传入异步数据生成的一个action对象,并使用dispatch提交
  • 组件中dispatch的写法不变

englishStore.js

import { createSlice } from "@reduxjs/toolkit";
const englishStore = createSlice({name: "englishstore",// 初始化状态initialState: {// 英文内容content: "",// 中文内容note: "",},// 修改内容reducers: {changeEnglish(store, action) {console.log(action.payload);store.content = action.payload.content;store.note = action.payload.note;},},
});// 结构出action对象中的方法
const { changeEnglish } = englishStore.actions;// 异步请求
const fetchEnglish = () => {return async (dispatch) => {const res = await fetch("https://api.oioweb.cn/api/common/OneDayEnglish");const data = await res.json();console.log(data);// 修改状态dispatch(changeEnglish(data.result));};
};// reducer函数
const englishReducer = englishStore.reducer;// 导出
export default englishReducer;
export { fetchEnglish };

使用


import { useEffect } from 'react';
import './App.css'
import { useSelector, useDispatch } from 'react-redux';
import { fetchEnglish } from './store/modules/englishStore';function App() {const englishReducer = useSelector(state => state.english)const dispatch = useDispatch()useEffect(() => {// 触发异步请求dispatch(fetchEnglish())}, [dispatch])return (<div><div>中文:{englishReducer.note}</div><div>英文:{englishReducer.content}</div></div>);
}export default App

在这里插入图片描述


http://www.ppmy.cn/embedded/121880.html

相关文章

Arduino使用网页连接修改esp8266等物联网并修改网络连接信息的基本思路

原因 这样不用每次修改程序中的代码&#xff0c;然后编译再传输到实物中。方便一般非嵌入式人员操作。基本就像买了一个需要联网的一个电子产品要进行的联网设置的操作 基本思路 参考视频图片来源 在硬件程序中&#xff0c;包含一个能够做为网页的请求数据字符串&#xff0c…

【接口测试】任务2:商品分类接口

需要技能竞赛软件测试资料的同学们可s聊我&#xff0c;详细了解 根据接口API文档&#xff0c;编写接口测试用例&#xff0c;分别使用PostMan及JMeter进行接口测试&#xff0c;需要检查系统接口是否能正常工作&#xff0c;返回值是否正确&#xff0c;保证接口调用的正确性。 Pos…

基于大数据的高校新生数据可视化分析系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…

会声会影导出视频mp4格式哪个最高清,会声会影输出格式哪个清晰

调高分辨率后&#xff0c;mp4视频还是不清晰。哪怕全部使用4K级素材&#xff0c;仍然剪不出理想中的高画质作品。不是你的操作有问题&#xff0c;而是剪辑软件没选对。Corel公司拥有全球顶尖的图像处理技术&#xff0c;该公司研发的会声会影视频剪辑软件&#xff0c;在过去的20…

我是如何写作的?

以前是如何写作的 从小学三年级开始学写作文&#xff0c;看的作文书&#xff0c;老师布置作文题目&#xff0c;内容我都是自己写的。那时会积累一些好词&#xff0c;听到什么好词就记住了。并没有去观察什么&#xff0c;也没有好好花心思在写作上。总觉得我写的作文与真正好的…

正向代理与反向代理:原理、区别以及应用(Nginx 和 Tomcat)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言1. 实现原理正向代理工作流程&#xff1a; 反向代理工作流程&#xff1a; 区别 2. 使用案例Nginx作为正向代理Nginx作为反向代理Tomcat作为反向代理 3. 适用场景…

【C++】模拟实现红黑树

&#x1f984;个人主页:修修修也 &#x1f38f;所属专栏:实战项目集 ⚙️操作环境:Visual Studio 2022 目录 一.了解项目功能 二.逐步实现项目功能模块及其逻辑详解 &#x1f4cc;实现RBTreeNode类模板 &#x1f38f;构造RBTreeNode类成员变量 &#x1f38f;实现RBTreeNode类构…

Golang | Leetcode Golang题解之第454题四数相加II

题目&#xff1a; 题解&#xff1a; func fourSumCount(a, b, c, d []int) (ans int) {countAB : map[int]int{}for _, v : range a {for _, w : range b {countAB[vw]}}for _, v : range c {for _, w : range d {ans countAB[-v-w]}}return }