当前位置: 首页 > news >正文

react + redux 状态管理操作

目录

  • 1 概念
  • 2 Redux 安装
  • 3 创建子模块并导入
  • 4 中间件为 react 注入 store
  • 5 在组件中使用 store 数据
  • 6 修改 store 数据
  • 7 提交 action 传参
  • 8 异步状态操作
  • 9 redux 调试工具

1 概念

Redux 是一个全局状态管理的 JS 库
在这里插入图片描述

2 Redux 安装

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

  • Redux Toolkit:官方推荐编写redux逻辑的方式,简化书写方式
  • react-redux:用来连接 redux 和 react 组件的中间件

通过命令:

npm i @reduxjs/toolkit react-redux

3 创建子模块并导入

创建如下目录结构
在这里插入图片描述

counterStore.js 代码如下:

import { createSlice } from "@reduxjs/toolkit";const counterStore = createSlice({name: 'counter',// 初始化stateinitialState: {count: 0},// 修改状态的方法 (同步方法)reducers: {increment(state) {state.count++},decrement(state) {state.count--}}
})// 解构出来action函数
const { increment, decrement } = counterStore.actions
// 获取reducer
const reducer = counterStore.reducer// 导出actions
export { increment, decrement }
// 默认导出reducer
export default reducer

其中,我们定义了数据:count
以及两个 action:increment / decrement,后续会通过 dispatch 来触发 action 修改数据

react 只有一种方式能够修改数据,就是 action,我们需要用 dispatch 提交 action,来修改数据

然后再将子模块 counterStore.js 引入
index.js 代码如下:

import { configureStore } from '@reduxjs/toolkit'
import counter from './modules/counterStore'// 导入子模块reducer
export default configureStore({reducer: {counter}
})

4 中间件为 react 注入 store

react-redux 负责把 react 和 redux 连接起来,内置 Provider 组件 通过 store 参数把创建好的 store 实例注入到应用中,连接正式建立
通过导入 store 和 Provider 后
使用 Provider 将 App 包裹起来

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

5 在组件中使用 store 数据

需要用到一个钩子函数 useSelector(),他的作用是把 store 的数据映射到组件中

import './App.css';
import { useSelector } from "react-redux";function App() {// 获得 count 数据const { count } = useSelector(state => state.counter)return (<div className="App">{count}</div>);
}export default App;

使用 {count} 语法,界面中会展示 count 初始值

6 修改 store 数据

需要另外一个 hook 函数 userDispatch,它的作用是生成提交 action 对象的 dispatch 函数
在这里插入图片描述

react 只有一种方式能够修改数据,就是 action,我们需要用 dispatch 提交 action,来修改数据

import './App.css';
import { useDispatch, useSelector } from "react-redux";
// 导入action 
import { increment, decrement } from './store/modules/counterStore.js'function App() {// 获得 count 数据const { count } = useSelector(state => state.counter)// 通过 dispatch 提交action 修改数据const dispatch = useDispatch()return (<div className="App"><button onClick={() => dispatch(decrement())}>-</button>{count}<button onClick={() => dispatch(increment())}>+</button></div>);
}export default App;

7 提交 action 传参

在调用 action 时,参数会被传递到 action 对象的 payload 属性上
在这里插入图片描述
在这里插入图片描述

import './App.css';
import { useDispatch, useSelector } from "react-redux";
// 导入action 
import { increment, decrement, addToNum } from './store/modules/counterStore.js'function App() {// 获得 count 数据const { count } = useSelector(state => state.counter)// dispatch 提交action 修改数据const dispatch = useDispatch()return (<div className="App"><button onClick={() => dispatch(decrement())}>-</button>{count}<button onClick={() => dispatch(increment())}>+</button><button onClick={() => dispatch(addToNum(10))}>+10</button></div>);
}export default App;
import { createSlice } from "@reduxjs/toolkit";const counterStore = createSlice({name: 'counter',// 初始化stateinitialState: {count: 0},// 修改状态的方法 (同步方法)reducers: {increment(state) {state.count++},decrement(state) {state.count--},addToNum(state, action) {state.count += action.payload}}
})// 解构出来action函数
const { increment, decrement, addToNum } = counterStore.actions
// 获取reducer
const reducer = counterStore.reducer// 导出actions
export { increment, decrement, addToNum }
// 默认导出reducer
export default reducer

8 异步状态操作

  • 创建 store 的 state 和 action 不变
  • 在子模块中单独封装一个函数,新函数中异步请求拿到数据,并使用 dispatch 触发 action
    在这里插入图片描述
    创建新的 store 模块
    store/modules/channelStore.js 代码如下:
import { createSlice } from "@reduxjs/toolkit";const channelStore = createSlice({name: 'channel',// 初始化stateinitialState: {channel: [{id: 50}, {id: 100}]},// 修改状态的方法 (同步方法)reducers: {setChannels(state, action) {state.channel = action.payload}}
})// 解构出来action函数
const { setChannels } = channelStore.actions
// 获取reducer
const reducer = channelStore.reducer// 异步请求
const fetchChannList = () => {return async (dispatch) => {setTimeout(() => {dispatch(setChannels([{id: 50}, {id: 100}, {id: 150}, {id: 200}]))})  // 模拟产生异步请求console.log('aaa')}
}// 导出异步方法
export { fetchChannList }
// 默认导出reducer
export default reducer

App.js 代码如下:

import './App.css';
import { useEffect } from 'react';
import { useDispatch, useSelector } from "react-redux";
// 导入action 
import { increment, decrement, addToNum } from './store/modules/counterStore.js'import { fetchChannList } from './store/modules/channelStore.js'function App() {// 获得 state 数据const { count } = useSelector(state => state.counter)const { channel } = useSelector(state => state.channel)// dispatch 提交action 修改数据const dispatch = useDispatch()// 使用useEffect触发异步请求useEffect(() => {dispatch(fetchChannList())}, [dispatch])return (<div className="App"><button onClick={() => dispatch(decrement())}>-</button>{count}<button onClick={() => dispatch(increment())}>+</button><button onClick={() => dispatch(addToNum(10))}>+10</button><ul>{channel.map(item => <li key={item.id}>{item.id}</li>)}</ul></div>);
}export default App;

9 redux 调试工具

谷歌下载:redux devtools

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Kafka基础入门篇(深度好文)
  • 柳永,市井生活的吟游者
  • HDFS体系架构文件写入/下载流程
  • EnableFeignClients详解
  • 函数的形状怎么定义?
  • 用Qwt进行图表和数据可视化开发
  • GD32F303之CAN通信
  • EasyExcel批量读取Excel文件数据导入到MySQL表中
  • 二分查找中while的判断条件
  • 11.FreeRTOS_事件组
  • 使用Python和MediaPipe实现手势虚拟鼠标控制
  • 自动驾驶论文总结
  • SQL 索引
  • PyTorch DataLoader 学习
  • 2024前端面试真题【CSS篇】
  • 实现windows 窗体的自己画,网上摘抄的,学习了
  • [case10]使用RSQL实现端到端的动态查询
  • Docker 笔记(2):Dockerfile
  • express.js的介绍及使用
  • extract-text-webpack-plugin用法
  • HTTP 简介
  • Laravel Telescope:优雅的应用调试工具
  • MySQL QA
  • npx命令介绍
  • Redux系列x:源码分析
  • Storybook 5.0正式发布:有史以来变化最大的版本\n
  • zookeeper系列(七)实战分布式命名服务
  • 分布式事物理论与实践
  • 开源地图数据可视化库——mapnik
  • 聊聊directory traversal attack
  • 异常机制详解
  • 鱼骨图 - 如何绘制?
  • 源码之下无秘密 ── 做最好的 Netty 源码分析教程
  • 白色的风信子
  • #HarmonyOS:Web组件的使用
  • #NOIP 2014# day.2 T2 寻找道路
  • $.ajax()方法详解
  • (4)Elastix图像配准:3D图像
  • (Arcgis)Python编程批量将HDF5文件转换为TIFF格式并应用地理转换和投影信息
  • (Python第六天)文件处理
  • (Redis使用系列) SpirngBoot中关于Redis的值的各种方式的存储与取出 三
  • (安卓)跳转应用市场APP详情页的方式
  • (保姆级教程)Mysql中索引、触发器、存储过程、存储函数的概念、作用,以及如何使用索引、存储过程,代码操作演示
  • (初研) Sentence-embedding fine-tune notebook
  • (创新)基于VMD-CNN-BiLSTM的电力负荷预测—代码+数据
  • (每日一问)基础知识:堆与栈的区别
  • (免费领源码)python+django+mysql线上兼职平台系统83320-计算机毕业设计项目选题推荐
  • (图文详解)小程序AppID申请以及在Hbuilderx中运行
  • (转)mysql使用Navicat 导出和导入数据库
  • (自适应手机端)响应式新闻博客知识类pbootcms网站模板 自媒体运营博客网站源码下载
  • .NET 5种线程安全集合
  • .NET 指南:抽象化实现的基类
  • .NET未来路在何方?
  • [ web基础篇 ] Burp Suite 爆破 Basic 认证密码
  • [2016.7 Day.4] T1 游戏 [正解:二分图 偏解:奇葩贪心+模拟?(不知如何称呼不过居然比std还快)]