Redux的简介及其在React中的应用

embedded/2024/11/14 19:35:43/

Redux

Redux 是React最常用的集中状态管理工具,类似于Vue中的Pinia(Vuex),可以独立于框架运行

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

使用步骤:

  1. 定义一个 reducer 函数 (根据当前想要做的修改返回一个新的状态);

  2. 使用createStore方法传入 reducer函数 生成一个store实例对象

  3. 使用store实例的 subscribe方法 订阅数据的变化(数据一旦变化,可以得到通知);

  4. 使用store实例的 dispatch方法提交action对象 触发数据变化(告诉reducer你想怎么改数据);

  5. 使用store实例的 getState方法 获取最新的状态数据更新到视图中。

 管理数据流程:

为了职责清晰,数据流向明确,Redux把整个数据修改的流程分成了三个核心概念,分别是:state、action和reducer

  1. state:一个对象 存放着我们管理的数据状态;

  2. action:一个对象 用来描述你想怎么改数据;

  3. reducer:一个函数 根据action的描述生成一个新的state。

 Redux与React环境准备

配套工具

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

  1. Redux Toolkit(RTK)- 官方推荐编写Redux逻辑的方式,是一套工具的集合集,简化书写方式

  2. react-redux - 用来 链接 Redux 和 React组件 的中间件。

配置基础环境

  1. 使用 CRA 快速创建 React 项目

    npx create-react-app react-redux
  2. 安装配套工具

    npm i @reduxjs/toolkit react-redux
  3. 启动项目

    npm run start

store目录结构设计

 

  1. 通常集中状态管理的部分都会单独创建一个单独的 store 目录

  2. 应用通常会有很多个子store模块,所以创建一个 modules 目录,在内部编写业务分类的子store

  3. store中的入口文件 index.js 的作用是组合modules中所有的子模块,并导出store

Redux与React 实现counter

 

使用React Toolkit 创建counterStore
javascript">// src => store => modules => counterStore.js
import { createSlice } from '@reduxjs/toolkit'const counterStore = createSlice({name: 'counter',//模块的名称// 初始化stateinitialState: {count: 0},// 修改数据的方法,都是同步方法,支持直接修改reducers: {incremnent(state) {state.count++},decrement(state) {state.count--}}
})// 解构出来actionCreater函数
const { incremnent, decrement } = counterStore.actions
// 获取reducer
const reducer = counterStore.reducer// 以按需导出的方式导出actionCreater
export { incremnent, decrement }
// 以默认导出的方式导出reducer
export default reducer
javascript">// src => store => index.js
import { configureStore } from "@reduxjs/toolkit";
// 导入子模块reducer
import counterReducer from "./modules/counterStore";const store = configureStore({reducer: {counter: counterReducer}
})export default store
为React注入store

react-redux负责把Redux和React 链接 起来,内置 Provider组件 通过 store 参数把创建好的store实例注入到应用中,链接正式建立。

javascript">// src => index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
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>
);// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
React组件使用store中的数据

在React组件中使用store中的数据,需要用到一个 钩子函数 - useSelector,它的作用是把store中的数据映射到组件中,使用样例如下:

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

React组件修改store中的数据

React组件中修改store中的数据需要借助另外一个hook函数 - useDispatch,它的作用是生成提交action对象的dispatch函数,使用样例如下:

javascript">import { useSelector, useDispatch } from 'react-redux'
// 导入actionCreater
import { incremnent, decrement } from './store/modules/counterStore'
function App() {const { count } = useSelector(state => state.counter)const dispathc = useDispatch()return (<div className="App"><button onClick={() => dispathc(decrement())}>-</button>{count}<button onClick={() => dispathc(incremnent())}>+</button></div>);
}
export default App;
Redux与React 提交action传参
  • 需求说明:

    组件中有俩个按钮 add to 10add to 20 可以直接把count值修改到对应的数字,目标count值是在组件中传递过去的,需要在提交action的时候传递参数

  • 提交action传参实现需求:

    • 在reducers的同步修改方法中添加action对象参数

    • 调用actionCreater的时候传递参数,参数会被传递到action对象payload属性上。

javascript">// src => app.js
import { useSelector, useDispatch } from 'react-redux'
// 导入actionCreater
import { incremnent, decrement, addToNum } from './store/modules/counterStore'
function App() {const { count } = useSelector(state => state.counter)const dispathc = useDispatch()return (<div className="App"><button onClick={() => dispathc(decrement(10))}>-</button>{count}<button onClick={() => dispathc(incremnent(10))}>+</button><button onClick={() => dispathc(addToNum(10))}>add to 10</button><button onClick={() => dispathc(addToNum(20))}>add to 20</button></div>);
}
export default App;
javascript">// src => store => counterStore.js
import { createSlice } from '@reduxjs/toolkit'
const counterStore = createSlice({name: 'counter',//模块的名称// 初始化stateinitialState: {count: 0},// 修改数据的方法,都是同步方法,支持直接修改reducers: {incremnent(state) {state.count++},decrement(state) {state.count--},addToNum(state, actions) {state.count = actions.payload}}
})
// 解构出来actionCreater函数
const { incremnent, decrement, addToNum } = counterStore.actions
// 获取reducer
const reducer = counterStore.reducer
// 以按需导出的方式导出actionCreater
export { incremnent, decrement, addToNum }
// 以默认导出的方式导出reducer
export default reducer
Redux与React 异步状态操作

 异步操作步骤:

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

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

    2.1 封装异步请求获取数据;

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

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

javascript">import { useSelector, useDispatch } from 'react-redux'
// 导入actionCreater
import { incremnent, decrement, addToNum } from './store/modules/counterStore'
import { useEffect } from 'react'
import { fetchChannelList } from './store/modules/channelStore'
function App() {const { count } = useSelector(state => state.counter)const { channelList } = useSelector(state => state.channel)const dispathc = useDispatch()// 使用useEffect触发异步请求执行useEffect(() => {dispathc(fetchChannelList())}, [])return (<div className="App"><button onClick={() => dispathc(decrement(10))}>-</button>{count}<button onClick={() => dispathc(incremnent(10))}>+</button><button onClick={() => dispathc(addToNum(10))}>add to 10</button><button onClick={() => dispathc(addToNum(20))}>add to 20</button><ul>{channelList.map((item) => (<li key={item.id}>{item.name}</li>))}</ul></div>);
}
export default App;
javascript">// src => store => modules => channelStore
import { createSlice } from "@reduxjs/toolkit";
import axios from "axios";
const channelStore = createSlice({name: 'channel',initialState: {channelList: []},reducers: {setChannels(state, actions) {state.channelList = actions.payload}}
})
// 异步请求部分
const { setChannels } = channelStore.actions
const fetchChannelList = () => {return async (dispathc) => {const res = await axios.get('http://geek.itheima.net/v1_0/channels')dispathc(setChannels(res.data.data.channels))}
}
export { fetchChannelList }
const reducer = channelStore.reducer
export default reducer


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

相关文章

PostgreSQL 性能优化全方位指南:深度提升数据库效率

PostgreSQL 性能优化全方位指南&#xff1a;深度提升数据库效率 别忘了请点个赞收藏关注支持一下博主喵&#xff01;&#xff01;&#xff01; 在现代互联网应用中&#xff0c;数据库性能优化是系统优化中至关重要的一环&#xff0c;尤其对于数据密集型和高并发的应用而言&am…

融云:社交泛娱乐出海机会尚存,跨境电商异军突起

近年来&#xff0c;直播、语聊房、游戏社区&#xff0c;这些中国网友熟悉的网络社交形式&#xff0c;正在海外市场爆发出新的生命力。无论是被炒到几百人民币一个的 Clubhouse 邀请码&#xff0c;还是先后登顶中东下载榜的 Yalla、JACO&#xff0c;这些快速掀起体验浪潮的社交娱…

React Native使用axios会不会有问题

React Native 编译成原生应用后&#xff0c;是会进行原生应用的编译&#xff0c;生成 iOS 或 Android 的应用包。但 Axios 作为一个 JavaScript 库&#xff0c;它的工作机制与传统的浏览器环境有所不同&#xff0c;因此需要进一步澄清。 Axios 在 React Native 中的工作原理&a…

《深度学习》bert自然语言处理框架

目录 一&#xff0c;关于bert框架 1、什么是bert 2、模型结构 自注意力机制&#xff1a; 3、预训练任务 4、双向性 5、微调&#xff08;Fine-tuning&#xff09; 6、表现与影响 二、Transformer 1、传统RNN网络计算时存在的问题 1&#xff09;串联 2&#xff09;并行…

vform2 表单数据回显问题

vform2 表单数据回显 问题解决办法 问题 ruoyi-flowable-plus 流程绑定的表单需要回显暂存的数据&#xff0c;使用JSON.stringify(this.$refs.vFormRef.getFormData(false))存储数据后&#xff0c;如果表单中含有上传组件并且存储时上传组件没有上传&#xff0c;使用this.$ref…

基于微信小程序的实习管理系统(附源码,文档)

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

Java版ERP管理系统源码解析:利用Spring Cloud Alibaba和Spring Boot实现微服务架构

ERP系统&#xff0c;亦称为企业资源计划系统&#xff0c;是一种融合了企业多元部门和复杂业务的综合管理信息系统。在全球经济蓬勃发展及企业竞争日趋激烈的背景下&#xff0c;ERP系统已逐步跃升为现代企业管理的核心工具。该系统通过优化资源配置及提升业务流程效率&#xff0…

计算网络信号

题目描述&#xff1a; 网络信号经过传递会逐层衰减&#xff0c;且遇到阻隔物无法直接穿透&#xff0c;在此情况下需要计算某个位置的网络信号值。注意&#xff1a;网络信号可以绕过阻隔物 array[m][n]的二维数组代表网格地图&#xff0c; array[i][j]0代表i行j列是空旷位置&…