Redux 使用及基本原理

什么是Redux

Redux 是用于js应用的状态管理库,通常和React一起用。帮助开发者管理应用中各个组件之间的状态,使得状态的变化变得更加可预测和易于调试。
Redu也可以不和React组合使用。(通常一起使用)

Redux 三大原则

单一数据源

  • 整个应用程序的state被存储在一棵obj tree中,这个obj tree只存储在一个store中;
  • redux 并没有强制让我们不能创建多个Store,但这样做不利于数据的维护;
  • 单一的数据源可以让整个应用程序的state变得方便维护,追踪,修改。

State是只读的

  • 唯一修改state的方法是触发action
  • 这样确保了View或网络请求都不能直接修改state,他们只能通过action来描述自己想要如何修改state;
  • 可以保证所有修改都被集中化处理,并按照严格的顺序来执行,所以不必担心race condition的问题。

使用纯函数来执行修改

  • 通过reducer将旧state和actions联系在一起,返回一个新的State
  • 随着应用程序的复杂度增加,我们可以将reducer拆分成多个小的reducers,分别操作不同state tree 的一部分
  • 但所有的reducers都应该是纯函数,不能产生任何的副作用。
    在这里插入图片描述

redux 如何使用

  1. 安装react-redux:
    yarn add react-redux
  2. 创建store 管理全局状态

src/store/constants.js

export const ADD_NUMBER = 'add_number'
export const SUB_NUMBER = 'sub_number'
export const CHANGE_BANNERS = 'change_banners'
export const CHANGE_RECOMMENDS = 'change_recommends'

创建reducer管理状态

src/store/reducers.js

import * as actionTypes from "./constants"const initialState = {counter: 100,banners: [],recommends: []
}
function reducer(state = initialState, action) {switch (action.type) {case actionTypes.ADD_NUMBER:return { ...state, counter: state.counter + action.num }case actionTypes.SUB_NUMBER:return { ...state, counter: state.counter - action.num }case actionTypes.CHANGE_BANNERS:return { ...state, banners: action.banners }case actionTypes.CHANGE_RECOMMENDS:return { ...state, recommends: action.recommends }default:return state}
}
export default reducer

src/store/index.js

import { createStore } from 'redux';
import reducer from './reducer';const store = createStore(reducer);export default store;

src/store/actionCreators.js
创建actionCreators,放修改状态的函数

import * as actionTypes from "./constants"
import axios from "axios"export const addNumberAction = (num) => ({type: actionTypes.ADD_NUMBER,num
})export const subNumberAction = (num) => ({type: actionTypes.SUB_NUMBER,num
})export const changeBannersAction = (banners) => ({type: actionTypes.CHANGE_BANNERS,banners
})export const changeRecommendsAction = (recommends) => ({type: actionTypes.CHANGE_RECOMMENDS,recommends
})export const fetchHomeMultidataAction = () => {// 如果是一个普通的action, 那么我们这里需要返回action对象// 问题: 对象中是不能直接拿到从服务器请求的异步数据的// return {}return function(dispatch, getState) {// 异步操作: 网络请求// console.log("foo function execution-----", getState().counter)axios.get("http://123.207.32.32:8000/home/multidata").then(res => {const banners = res.data.data.banner.listconst recommends = res.data.data.recommend.list// dispatch({ type: actionTypes.CHANGE_BANNERS, banners })// dispatch({ type: actionTypes.CHANGE_RECOMMENDS, recommends })dispatch(changeBannersAction(banners))dispatch(changeRecommendsAction(recommends))})}// 如果返回的是一个函数, 那么redux是不支持的// return foo
}
  1. 在项目index.js 根节点引用
    src/index.js
import {Provider} from 'react-redux'
import store from 'react-redux'const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(<React.StrictMode><Provider store={store}><App /></Provider></React.StrictMode>
);
  1. 在需要使用redux的页面或组件中,通过connect高阶组件映射到该组件的props中,解耦store和class组件的耦合。
    在这里插入图片描述

redux中异步操作

redux也引入了中间件的概念:

  • 目的是在dispatch的action和最终达到的reducer之间,扩展一些自己的代码
  • 比如日志记录,调用异步接口,添加代码调试功能等

发送异步网络请求,可以添加对应的中间件

  • 官网推荐 redux-thunk

redux-thunk 如何可以发送异步请求

  • 默认情况下的dispatch(action),action需要是一个js对象
  • redux-thunk可以让dispatch(action函数),action可以是一个函数
  • 该函数会被调用,并会传给这个函数一个dispatch函数和getState函数
  • dispatch函数用于我们之后再次派发action
  • getState 函数考虑我们之后的一些操作需要依赖原来的状态,用于让我们可以获取之前的一些状态

如何使用redux-thunk

  1. 安装redux-thunk
    yarn add redux-thunk
  2. 创建store时传入应用了middleware的enhance函数
  • 通过applyMiddleware来结合多个Middleware,返回一个enhancer;
  • 将enhancer作为第二个参数传入到createStore中;
// 通过applyMiddleware来结合多个Middleware, 返回一个enhancer
const enhancer = applyMiddleware(thunkMiddleware);
// 将enhancer作为第二个参数传入到createStore中
const store = createStore(reducer, enhancer);
  1. 定义返回一个函数的action:
  • 注意:这里返回一个函数
  • 该函数在dispatch之后会被执行
const getHomeMultidataAction = () => {return (dispatch) => {axios.get("http://123.207.32.32:8000/home/multidata").then(res => {const data = res.data.data;dispatch(changeBannersAction(data.banner.list));dispatch(changeRecommendsAction(data.recommend.list));})}
}

combineReducers函数

  • 事实上,redux给我们提供了一个combineReducers函数可以让我们方便对多个reducer进行合并
  • 那么combineReducers是如何实现的?
    • 它也是将我们传入的reducers合并到一个对象中,最终返回一个combination函数(相当于我们之前的reducer函数)
    • 在执行combination函数的过程中,它会通过判断前后返回的数据是否相同来决定返回之前的state还是新的state。
    • 新的state会触发订阅者发生对应的刷新,而旧的state可以有效的组织订阅者发生刷新。

Redux 基本原理

所有的状态都以对象树的方式(state)存放于单个store中。
唯一改变状态树(state tree)的方法是创建action:一个描述发生了什么的对象,并将其dispatch派发给store。要指定状态树如何响应action来进行更新,你可以编写纯reducer函数,这些函数根据旧的state和action来计算新state。
新的state被创建后,对象会自动传递给所有注册了监听器的组件,从而触发组件的重新渲染,使得界面始终保持与当前的state对象一致。
在这里插入图片描述
在这里插入图片描述

Redux在React中具体的使用方法

官方建议,安装其他两个插件 Redux Toolkit和React-Redux

  1. React Toolkit(RTK):官方推荐编写Redux逻辑的方式,是一套工具的集合,简化书写方式
  2. React-Redux:用来链接 Redux和React组件的中间件
    在这里插入图片描述
  3. 安装方式
    npm install @reduxjs/toolkit react-redux

Redux Toolkit(RTK)

1. createSlice 函数

作用:创建一个Redux的slice。它接受一个包含reducer函数,slice名称和初始状态的配置对象,并返回一个包含reducer和action creators的对象。
参数

  • name:slice的名称,用于标识状态的一部分。
  • initialState:slice的初始状态,定义了状态的初始值‘
  • reducers:一个对象,包含一组同步的reducer函数,用于更新状态。
    返回值:
    createSlice 返回一个包含以下属性的对象:
  • name:slice的名称
  • reducer:一个reducer 函数,用于处理来自action creators的动作并更新状态
  • actions:一组action creators,用于创建派发给reducer的动作。

栗子 🌰:

import { createSlice } from '@reduxjs/toolkit';// 定义初始状态
const initialState = {count: 0,
};// 创建一个 Redux slice
const counterSlice = createSlice({name: 'counter',initialState,reducers: {// 定义同步的 reducer 函数increment(state) {state.count += 1;},decrement(state) {state.count -= 1;},// 可以接受额外参数的 reducer 函数incrementByAmount(state, action) {state.count += action.payload;},},
});// 导出action creators
export const { increment, decrement, incrementByAmount } = counterSlice.actions;
// 导出reducer
export default counterSlice.reducer;

上述代码使用 createSlice 函数创建一个名为 counter 的slice。包含一个名为 count的状态和三个同步的reducer函数:increment,derement和incrementByAmount。

  • 通过increment,decrement,incrementByAmount 派发动作
    通过counterSlice.reducer 处理动作

configureStore 函数

作用:创建一个Redux store,它接受一个包含reducer函数和其他配置选项的对象,并返回一个Redux store 实例。
参数

  • reducer:一个或多个reducer函数,用于处理来自action creators 的动作并更新状态
  • 其他配置选项:包括 middleware,devTools 等,用于配置store的行为。
    返回值
  • configureStore 返回一个Redux store 实例,它包含以下属性和方法:
    • getState():用于获取当前的状态
    • dispatch(action):用于派发一个动作,以触发状态的更新
    • subscribe(listener):用于添加一个状态变化的监听器,当状态发生变化时会被调用
    • replaceReducer(nextReducer):用于替换当前的reducer

栗子🌰:

import { configureStore } from '@reduxjs/toolkit';
import rootReducer from './reducers'; // 导入根 reducer// 创建 Redux store
const store = configureStore({reducer: rootReducer,// middleware: getDefaultMiddleware => getDefaultMiddleware(), // 使用默认的中间件// devTools: process.env.NODE_ENV !== 'production', // 在开发环境启用 Redux DevTools
});export default store

在栗子中,我们使用configureStore 函数创建了一个Redux store
我们传入了一个根reducer rootReducer,它是一个包含所有reducer的对象。我们还配置了默认的中间件,并在开发环境下启用了Redux DevTools。

react-redux

它将所有组件分为两大类:UI 组件和容器组件。

  1. UI 组件:负责呈现页面(React)
  2. 容器组件:负责管理数据和业务逻辑(Redux)

react-redux中常用的组件及方法

Provider 组件

作用:将Redux的store 传递给整个React应用程序,使得所有组件都能够访问到redux的状态。通过provider,我们可以在任何地方使用redux的状态和派发动作。

好处:在整个应用程序中,任何一个组件都可以通过connect函数或useSelector钩子函数来访问Redux store 中的状态,而不需要手动将store传递给每一个组件。

  • 简化代码:不需要在每一个组件中手动传递store,通过Provider,store可以在整个应用程序中自动传递给需要的组件。
  • 避免prop drilling:避免了在组件层级结构中进行多层次的prop 传递,提高了代码的可维护性和可读性。
  • 一致性:所有的组件都使用相同的redux store,保证了应用程序状态的一致性。
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";import store from './store';
import { Provider } from 'react-redux';const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<Provider store={store}><App /></Provider>
)

参考

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

武汉星起航:无锡跨境电商加速“出海”,物流升级助品牌全球布局

随着全球化的不断深入&#xff0c;跨境电商作为数字外贸的新业态&#xff0c;正逐渐成为无锡企业拓展海外市场的重要渠道。武汉星起航关注到&#xff0c;近年来&#xff0c;无锡市通过积极推进国际物流枢纽建设&#xff0c;完善海外仓布局&#xff0c;以及各特色产业带的积极参…

2024 年江西省研究生数学建模竞赛题目 A题交通信号灯管理--完整思路、代码结果分享(仅供学习)

交通信号灯是指挥车辆通行的重要标志&#xff0c;由红灯、绿灯、 黄灯组成。红灯停、绿灯行&#xff0c;而黄灯则起到警示作用。交通 信号灯分为机动车信号灯、非机动车信号灯、人行横道信号 灯、方向指示灯等。 一般情况下&#xff0c;十字路口有东西向和南北向 4 个方向的车…

SpringSecurity中文文档(Servlet Session Management)

Authentication Persistence and Session Management 一旦您拥有了正在对请求进行身份验证的应用程序&#xff0c;就必须考虑如何在将来的请求中持久化和恢复结果身份验证。 默认情况下&#xff0c;这是自动完成的&#xff0c;因此不需要额外的代码&#xff0c;尽管了解 requ…

手机歌曲怎么转换成mp3格式,手机电脑都能轻松搞定

不同的手机和音乐应用可能支持不同的音频格式&#xff0c;而MP3作为一种广泛兼容的音频格式&#xff0c;因其体积小、音质相对较好的特点&#xff0c;至今仍被广泛使用。 如果您想将手机中的歌曲转换成MP3格式&#xff0c;以便于在更多设备上播放或节省存储空间&#xff0c;本…

iOS端授权页添加自定义按钮

如何添加自定义控件 基于一键登录的拉起授权页面功能&#xff0c;如果想要在我们的授权页面中添加自定义组件&#xff0c;例如使用其他方式登录的按钮&#xff0c;来实现其他方式登录功能&#xff0c;为用户呈现更多选择登录的方式。本文介绍如何在一键登录授权界面中实现添加…

机器学习之监督学习

整理一下机器学习中监督学习相关内容&#xff0c;争取梳理出一条易于理解和掌握的脉络。下面会有很多相关参考博客和文章&#xff0c;先放到一起&#xff0c;最后再做个整体的梳理。持续更新中。。。。。。 监督学习作为机器学习的核心分支&#xff0c;其理论体系与实践应用都…

C# 警告 warning MSB3884: 无法找到规则集文件“MinimumRecommendedRules.ruleset”

警告 warning MSB3884: 无法找到规则集文件“MinimumRecommendedRules.ruleset” C:\Program Files\Microsoft Visual Studio\2022\Professional\MSBuild\Current\Bin\amd64\Microsoft.CSharp.CurrentVersion.targets(129,9): warning MSB3884: 无法找到规则集文件“MinimumRe…

竞赛选题 python的搜索引擎系统设计与实现

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; python的搜索引擎系统设计与实现 &#x1f947;学长这里给一个题目综合评分(每项满分5分) 难度系数&#xff1a;3分工作量&#xff1a;5分创新点&#xff1a;3分 该项目较为新颖&#xff…

正则表达式在Java中的应用与实例

正则表达式在Java中的应用与实例 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 正则表达式是一种强大的工具&#xff0c;用于模式匹配和字符串处理。在Java中…

武汉星起航:成功挂牌上股交,引领跨境电商行业进入全新发展阶段

2023年10月30日&#xff0c;武汉星起航电子商务有限公司在上海股权托管交易中心成功挂牌展示&#xff0c;这一里程碑式的事件标志着武汉星起航正式登陆资本市场&#xff0c;开启了公司发展的新篇章。作为亚马逊跨境电商领域的领军企业之一&#xff0c;武汉星起航此次挂牌不仅是…

文件操作详解(C语言)

1.为什么要用到文件&#xff1f;怎样数据才能持久化&#xff1f; 保存在内存中的数不安全&#xff08;一次断电&#xff0c;忘记保存&#xff0c;不用了还给系统&#xff09; 持久化&#xff1a;保存在硬盘上&#xff08;放在文件中&#xff09; 什么是文件&#xff1f;文件…

Hadoop-08-HDFS集群 基础知识 命令行上机实操 hadoop fs 分布式文件系统 读写原理 读流程与写流程 基本语法上传下载拷贝移动文件

章节内容 上一节完成&#xff1a; HDFS的简介内容HDFS基础原理HDFS读文件流程HDFS写文件流程 背景介绍 这里是三台公网云服务器&#xff0c;每台 2C4G&#xff0c;搭建一个Hadoop的学习环境&#xff0c;供我学习。 之前已经在 VM 虚拟机上搭建过一次&#xff0c;但是没留下…

SpringSecurity的执行原理

SpringSecurity的执行原理&#xff1a;当我们服务端接收到请求后&#xff0c;首先通过DelegatingFilterProxy代理对象交互&#xff0c;转发给springsecurity的执行链&#xff0c;由于他自带的执行链有16条&#xff0c;我们将不用的过滤器进行了排除&#xff0c;同时加入了我们自…

如何保护应用?可快速部署的WAF服务器分享

Web应用攻击是安全事件和数据泄露的主要原因。相关统计表明&#xff0c;超过四分之三的网络犯罪直指应用及其漏洞。为保护数量日益增长的应用安全&#xff0c;Web应用防火墙(WAF)因此而生。本文则聚焦于WAF服务器&#xff0c;了解它的性能与具体的实践应用。   新加坡网络安全…

《单片机》期末考试复习-学习笔记总结

题型 问答题(15分)编程题(65分)编程题1(20分)编程题2(45分)设计题(20分)一、问答题 1.1.单片机概念和特点 1.2. 51单片机的中断结构 1.3.主从式多机通讯的概念及其工作原理 多机通信是指两台以上计算机之间的数据传输,主从式多机通信是多机通信系统中最简单的一种,…

PHP电商系统开发指南最佳实践

电子商务系统开发的最佳实践包括&#xff1a;数据库设计&#xff1a;选择适合关系型数据库&#xff0c;优化数据结构&#xff0c;考虑表分区&#xff1b;安全&#xff1a;加密数据&#xff0c;防止 sql 注入&#xff0c;处理会话管理&#xff1b;用户界面&#xff1a;遵循 ux 原…

vue3长列表优化,使用vue-virtual-scroller实现直播间弹幕列表虚拟滚动效果

使用的组件库是&#xff1a;https://github.com/Akryum/vue-virtual-scroller 官方文档&#xff1a;vue-virtual-scroller 安装依赖 npm install --save vue-virtual-scrollernextpnpm install --save vue-virtual-scrollernextyarn add vue-virtual-scrollernext 组件导入…

如何用文章改写ai软件进行改写?5个软件教你快速进行修改文章

如何用文章改写ai软件进行改写&#xff1f;5个软件教你快速进行修改文章 使用AI改写软件可以帮助你快速重写文章&#xff0c;使其更加流畅、符合要求或避免重复。以下是五款优质的AI改写软件&#xff0c;它们能够帮助你快速进行文章修改&#xff1a; 聪明灵犀 这是一款非常简…

数据结构_1.0

一、数据结构概述 1.1 概念 在计算机科学中&#xff0c;数据结构是一种数据组织、管理和存储的格式 。它是相互之间存在一种或多种特定关系的数据元素的集合。通常情况下&#xff0c;精心选择的数据结构可以带来更高的运行或者存储效率。数据结构往往同高效的检索算法和索引技…

【开源合规】开源许可证基础知识与风险场景引入

文章目录 什么是开源许可证(License)?开源许可证有什么用?开源许可证分类开源许可证分类及描述公共代码 (Public Domain)CC0无License宽松型许可证 (Permissive)MITApache 2.0BSD弱互惠型许可证 (Weak Copyleft)LGPLMPLEPL互惠型许可证 (Reciprocal)GPLEUPL强互惠许可证 (Str…