Redux的基本使用过程详解

news/2024/5/17 18:18:58/文章来源:https://blog.csdn.net/m0_71485750/article/details/126732471

文章目录

    • Redux的使用过程
      • Redux测试项目的搭建
      • Redux的基本使用步骤
      • Redux目录的结构划分
      • React的三大原则

Redux的使用过程

Redux测试项目的搭建

1.创建一个新的项目文件夹:learn-redux

# 执行初始化操作 npm init -yyarn init -y

# 安装redux:npm install redux --saveyarn add redux

2.创建src目录,在src目录下创建一个store文件夹, 并且在该文件夹下创建index.js文件

3.可以修改package.json用于执行index.js, 也可以不配置, 直接使用node命令运行

"scripts": {"start": "node src/index.js"
}

Redux的基本使用步骤

1.创建一个对象,作为我们要保存的状态state:

// 由于测试项目在node环境下, 因此使用require方式导入
const { createStore } = require("redux")// 创建的要存储的state: initialState
const initialState = {name: "chenyq",age: 18
}

2.创建Store来存储这个state

由于创建的state是不能直接放到创建的store中的, 需要通过reducer将数据添加到store中, 因此创建store时必须创建reducer;

reducer函数的返回值, 会作为store之后存储的state

// 定义reducer, 将要存储的state作为返回值返回
function reducer() {return initialState
}// 创建的store, 内部会自动回调reducer, 拿到initialState
const store = createStore(reducer)// 导出store
module.exports = store

我们可以在其他文件中通过 store.getState 来获取当前的state;

// 导入创建的store
const store = require("./store")// 获取store中的state
console.log(store.getState())

在这里插入图片描述

3.通过action来修改state

错误演示: 直接修改store

store.getState().name = "abc"

修改store中的数据不能直接修改, 必须要通过dispatch来派发action;

通常action中都会有type属性,也可以携带其他的数据;

// 定义一个action
const nameAction = { type: "change_name", name: "abc" }
// 派发action
store.dispatch(nameAction)

当然上面代码中, 也可以写为一行

// 派发action
store.dispatch({ type: "change_name", name: "abc" })

4.修改reducer中的处理代码

reducer接收两个参数:

参数一: store中当前保存的state

参数二: 本次需要更新的action

只要调用dispatch就会重新执行reducer函数

这里一定要记住,reducer是一个纯函数,不可以直接修改state, 后面我会讲到直接修改state带来的问题;

// 第一次state是undefined, 因此给一个默认值将初始化数据添加到store中
function reducer(state = initialState, action) {// 有数据更新时, 返回一个新的stateif (action.type === "change_name") {return { ...state, name: action.name }}// 没有数据更新时, 返回之前的statereturn state
}

5.可以在派发action之前,监听store的变化:

通过store.subscribe()函数可以监听store中的数据变化

store.subscribe()函数的参数接收一个函数, 该函数在store数据发生更新自动回调

const store = require("./store")// 例如: 监听数据的变化, 当store变化, 就获取最新的state
store.subscribe(() => {console.log(store.getState())
})store.dispatch({ type: "change_name", name: "abc" })
store.dispatch({ type: "change_name", name: "aaa" })

6.封装函数动态生成action

例如上面代码中, 我们修改名称多次, 只有传入的action的name属性值不相同, 那么我们可以封装一个函数, 动态的生成action, 这也是开发中一贯的做法

// 创建修改name的action
const changeNameAction = (name) => ({type: "change_name",name
})
// 创建修改age的action
const changeAgeAction = (num) => ({type: "change_age",num
})// 在派发action时, 我们就可以调用函数即可获取action
store.dispatch(changeNameAction("aaa"))
store.dispatch(changeNameAction("bbb"))
store.dispatch(changeNameAction("ccc"))store.dispatch(changeAgeAction(10))
store.dispatch(changeAgeAction(20))
store.dispatch(changeAgeAction(30))
store.dispatch(changeAgeAction(40))

Redux目录的结构划分

如果我们将所有的逻辑代码写到一起,那么当redux变得复杂时代码就难以维护

例如上面代码中, 我们封装的动态创建action的函数, 这种动态生成action的函数在项目中可能会有很多个, 而且在其他多个文件中也可能会使用, 所以我们最好是有一个单独的文件夹存放这些动态获取action的函数

接下来,我会对代码进行拆分,将store、reducer、action、constants拆分成一个个文件。

创建store/index.js文件: index文件中, 我们只需要创建store即可

const { createStore } = require("redux")
// 引入reducer
const reducer = require("./reducer")// 创建的store, 内部会自动回调reducer, 拿到initialState
const store = createStore(reducer)// 导出store
module.exports = store

创建store/reducer.js文件: 在真实项目中, reducer这个函数我们会越写越复杂, 造成我们index.js文件越来越大, 所以我们将reducer也抽离到一个单独的文件中

const { CHANGE_NAME, CHANGE_AGE } = require("./constants")// 创建的要存储的初始化state
const initialState = {name: "chenyq",age: 18
}// 定义reducer, 将要存储的state作为返回值返回
// 第一次state是undefined, 因此给一个默认值将初始化数据添加到store中
function reducer(state = initialState, action) {switch(action.type) {case CHANGE_NAME: return { ...state, name: action.name }case CHANGE_AGE: return {...state, age: state.age + action.num}}// 没有数据更新时, 返回之前的statereturn state
}module.exports = reducer

创建store/constants.js文件: 将type的类型定义为常量(防止写错的情况), 这些常量最好也防止一个单独的文件中

// store/constants.jsconst CHANGE_NAME = "change_name"
const CHANGE_AGE = "change_age"module.exports = {CHANGE_NAME,CHANGE_AGE
}

创建store/actionCreators.js文件: 将封装的动态创建action的函数放在该文件中, 在需要使用的地方导入即可

const { CHANGE_NAME, CHANGE_AGE } = require("./store/constants")// 创建修改name的action
const changeNameAction = (name) => ({type: CHANGE_NAME,name
})
// 创建修改age的action
const changeAgeAction = (num) => ({type: CHANGE_AGE,num
})module.exports = {changeNameAction,changeAgeAction
}

最终形成如下目录结构, 这也是官方推荐的目录结构, 一个store中包含这四个文件夹

在这里插入图片描述

注意:node中对ES6模块化的支持, 建议使用CommonJS规范


React的三大原则

单一数据源

整个应用程序的state被存储在一颗object tree中,并且这个object tree只存储在一个 store 中:

Redux并没有强制让我们不能创建多个Store,但是那样做并不利于数据的维护;

单一的数据源可以让整个应用程序的state变得方便维护、追踪、修改;

State是只读的

唯一修改State的方法一定是触发action,不要试图在其他地方通过任何的方式来修改State:

这样就确保了View或网络请求都不能直接修改state,它们只能通过action来描述自己想要如何修改state;

这样可以保证所有的修改都被集中化处理,并且按照严格的顺序来执行,所以不需要担心race condition(竟态)的问题;

使用纯函数来执行修改

通过reducer将旧state和actions联系在一起,并且返回一个新的State:

随着应用程序的复杂度增加,我们可以将reducer拆分成多个小的reducers,分别操作不同state tree的一部分;

但是所有的reducer都应该是纯函数,不能产生任何的副作用;

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

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

相关文章

自定义View 布局过程(Layout)

目录一、作用二、layout过程详解2.1单一View的layout过程具体使用具体流程源码分析总结2.2ViewGroup的layout过程具体使用具体流程源码分析总结三、细节问题:getWidth() ( getHeight())与 getMeasuredWidth() (getMeasuredHeight(…

Java高级——编译JDK

编译JDKJDK是什么?编译环境搭建JDK下载编译参数编译在IDE中调试源码JDK是什么? Java Development Kit,用于执行和开发java程序 编译环境搭建 本文采用Ubantu 18.04 执行以下命令安装依赖 apt-get install build-essential apt-get instal…

Transformer

参考 https://www.ylkz.life/deeplearning/p12158901/ https://zhuanlan.zhihu.com/p/396221959 模型结构 Input Embedding 将文本中词汇的数字表示转变为向量表示, 希望得到其在高维空间中的特征表示向量。 # 导入必备的工具包 import torch import torch.nn as nn import …

Qt5开发从入门到精通——第九篇一节( Qt5 文件及磁盘处理—— 读写文本文件)

CSDN话题挑战赛第2期 参赛话题:学习笔记 欢迎小伙伴的点评✨✨,相互学习c/c应用开发。🍳🍳🍳 博主🧑🧑 本着开源的精神交流Qt开发的经验、将持续更新续章,为社区贡献博主自身的开源精…

esp32-C3 CAN接口使用

esp32-C3 CAN接口使用功能概述CAN协议关注点接收过滤器单过滤器模式双过滤器模式关键函数说明配置和安装驱动获取TWAI状态信息发送/接收消息使用示例CAN控制器自回环测试CAN收发带过滤测试功能概述 ESP32-C3具有1个CAN控制器支持以下特性: 兼容ISO 11898-1协议(CA…

伟大的micropython smartconfig 配网它来了!!!

我这其实只是实验和搬运,还是感谢伟大的walkline群主,他弄好的,我只是负责搬运发布给新手看。 之前一大堆人问我配网的事儿,输入下wifi名称密码这么麻烦吗,好吧,有求必应,之前的配网是通过ap模式…

PICO高管专访:关于PICO 4硬件、内容、定价、海外布局的一切解答

PICO 4昨天正式在国内发布,简单来说这是一款相对均衡的VR一体机,在硬件素质、内容生态建设上都可圈可点,对于国内还未入手VR的朋友们来说是非常好的选择。相关阅读:《PICO 4评测:Pancake光学新标杆,VR娱乐V…

20【访问者设计模式】

文章目录二十、访问者设计模式20.1 访问者设计模式简介20.1.1 访问者设计模式概述20.1.2 访问者设计模式的UML类图20.2 访问者设计模式的实现20.3 访问者设计模式的优缺点二十、访问者设计模式 20.1 访问者设计模式简介 20.1.1 访问者设计模式概述 访问者设计模式&#xff0…

计算机网络基础 VLSM----可变长子网掩码;CIDR技术----无类域间路由;

VLSM----可变长子网掩码: 概述: 通过网络位向主机位借位的方式,延长子网掩码,从而达到将一个大网络划分为多个小网络;借出的位数称之为子网位,决定了能划分网络的个数。 优点: 更高效的利用…

记一次导入下载好的源码工程到本地工程异常解决方案

今天在学习okhttp相关视频时,安装视频的操作在自己的工程中引入三方的模块,但是发现引入后和预期的不一致。不一致指的是,视频中以module方式引入sample-okhttp并解决冲突后,sample-okhttp能够被android stuidio识别为applicayion…

Style样式设置器

构成Style最重要的两种元素: Setter类帮助我们设置控件的静态外观风格 Trigger类则帮助我们设置控件的行为风格。 Setter,设置器,我们给属性赋值的时候一般都采用“属 性名属性值”的形式 上面的例子中针对TextBlock的Style,Style中使用 若…

解决csdn强制关注博主才能阅读文章

问题 有的时候查阅资料的时候,关注博主并不是很方便,查csdn会出现下面的提示解决办法 打开控制台输入以下代码: var article_content=document.getElementById("article_content"); article_content.removeAttribute("style");var follow_text=document…

深入理解计算机系统——第七章 Linking

深入理解计算机系统——第七章 Linking7.1 Compiler Drivers7.2 Static Linking7.3 Object Files7.4 Relocatable Object Files7.5 Symbols and Symbol Tables7.6 Symbol Resolution7.6.1 How Linkers Resolve Duplicate Symbol Names7.6.2 Linking with Static Libraries7.6.3…

人体神经元结构示意图,神经细胞内部结构图

人体神经结构图???? 谷歌人工智能写作项目:神经网络伪原创 下图为神经系统的结构示意图,请根据图回答: (1)构成神经系统的结构、功能单位是神经元,图中E部分…

19【迭代器设计模式】

文章目录十九、迭代器设计模式19.1 迭代器设计模式简介19.1.1 迭代器设计模式概述19.1.2 迭代器设计模式的UML类图19.2 迭代器设计模式的实现19.3 迭代器设计模式的优缺点十九、迭代器设计模式 19.1 迭代器设计模式简介 19.1.1 迭代器设计模式概述 迭代器设计模式&#xff0…

DeFi借贷重新洗牌 透过协议变化能找到哪些新趋势?

在过去的几个月里,DeFi 借贷赛道产生了重大变化,1kx 研究员 Mikey 0x 对此场域重新进行梳理,BlockBeats 对其整理翻译如下: 本文内容将包括对新借贷协议的介绍、核心数据统计以及发展趋势,也许可以让我们大致把握下一…

Python3操作MongoDB数据库

Python3操作MongoDB数据库 文章目录Python3操作MongoDB数据库0. 写在前面1. 安装开源驱动库pymongo2. 参考0. 写在前面 Linux:Ubuntu Kylin 16.04MongoDB:MongoDB3.2.7Python:Anaconda With Python3.7 1. 安装开源驱动库pymongo pymongo驱动…

公众号题库搜题对接(免费接口)

公众号题库搜题对接(免费接口) 本平台优点: 多题库查题、独立后台、响应速度快、全网平台可查、功能最全! 1.想要给自己的公众号获得查题接口,只需要两步! 2.题库: 题库:题库后台(点击跳转&a…

用神经网络表示与逻辑,神经网络实现逻辑运算

数据挖掘中的神经网络和模糊逻辑的概念是啥? 【神经网络】人工神经网络(Artificial Neural Networks,简写为ANNs)也简称为神经网络(NNs)或称作连接模型(Connection Model)&#xff…

Frp内网穿透win系统实录

文章目录前言公网服务器端配置基于Docker配置简单文件配置内网服务器端配置frpc配置安装OpenSSH服务配置连接XShell和Xftp连接前言 由于实验室的某些原因,分配了一台win10的服务器(QAQ),但是由于服务器在内网,无法访问…