实习的时候,公司使用的是react,react说实话生态学的还不是很完善,就暂时先不做跟react相关的博客,等以后学好了react全家桶之后,专门再总结一下react的内容

这两天看了公司的alita和dva,具体项目还没上手,但是对dva很感兴趣,一方面因为dva名字的由来,另一方面刚好在看redux的内容。

在讲redux的时候,不得不把vuex拿出来讲讲,说实话,vuex很久之前学的了,vue是我前端框架第一次接触的,vue的方便性也让我很喜爱,但是身为一个前端攻城狮怎么能不学其他框架呢,趁着在公司实习的日子里,把react的学习提上日程

扯远了,回到redux和vuex中。redux是一个状态数据的管理库,它可以用在react,也可以用在vue中,但是vue自己有一个vuex,兼容性更好,所以更大多数redux用在react的项目中。

学习vuex的时候,与现在的redux做对比,很清晰能比较出来,vuex比redux简单

下图是vuex的工作流程原理

VueX是数据管理框架,在之前我们vue里面的数据是data,父子组件,provide等等传递 在vue工程里面,数据就不是组件级别的创建,而是页面级别的创建了

VueX创建了全局的仓库,在vuex的state中,存放在全局的数据。我们使用vuex提供的store对象的state属性,来获取全局的数据

export default{
  name:'Home',
  computed:{
    myName(){
      return this.$store.state.name;
    }
  }
}

我们如何修改全局的数据?Vuex不允许我们直接修改全局的数据

因此我们要 调用$store里面一个方法叫做dispatch,他去派发一个action,这个action的名字叫做change 在createStore里就有一个action接收派发而来的change,执行这个change方法。在这个方法中提交一个commit触发一个mutation,在mutations里面接收触发而来方法并执行,在该方法中我们就可以修改数据

vuex的工作流程就是,组件之间使用dispatch去派发一个action,vuex中主要有三个属性action,commit,state用来操作管理数据。

actions感知到组件所派发的action,执行action对应参数的方法,提交一个commit去触发mutation,mutation中执行收到的commit的参数方法。从而修改state数据,而这个state数据就是全局的数据仓库

在最近的学习中,我接触到了redux,说实话,redux复杂程度高于vuex。

react整个应用中会存在很多个组件,每个组件的state是由自身进行管理,包括组件定义自身的state、组件之间的通信通过props传递、使用Context实现数据共享

将所有的状态进行集中管理,当需要更新状态的时候,仅需要对这个管理集中处理,而不用去关心状态是如何分发到每一个组件内部的

redux就是一个实现上述集中管理的容器,遵循三大基本原则:

  • 单一数据源
  • state 是只读的
  • 使用纯函数来执行修改

redux要求我们把数据都放在 store公共存储空间

一个组件改变了 store 里的数据内容,其他组件就能感知到 store的变化,再来取数据,从而间接的实现了这些数据传递的功能

React Components (组件)需要获取一些数据, 然后它就告知 Store 需要获取数据,这就是 Action Creactor , Store 接收到之后去 Reducer 查一下, Reducer 会告诉 Store 应该给这个组件什么数据

如何使用?

创建一个store

import { createStore } from 'redux' // 引入redux
const store = createStore() // 创建数据的公共存储区域

还需要创建一个记录本去辅助管理数据,也就是reduecer,本质就是一个函数,接收两个参数state,action,返回state

// 设置默认值
const initialState = {
counter: 0
} const reducer = (state = initialState, action) => {
}

将记录本传递给store,两者建立连接,获取store里面的数据,则通过store.getState()来获取当前state

const store = createStore(reducer)
store.getState()

那么如何更改store中的数据呢?

是通过dispatch来派发action,通常action中都会有type属性,还有传入的更改数据。

type属性代表这个action所要做的操作

store.dispatch({
type: "ADD_NUMBER",
number: 5
})

ruducer中处理所要进行操作,使用swich去接收不同action所代表的操作方法

const reducer = (state = initialState, action) => {
switch (action.type) {
case "INCREMENT":
return {...state, counter: state.counter + 1};
case "DECREMENT":
return {...state, counter: state.counter - 1};
case "ADD_NUMBER":
return {...state, counter: state.counter + action.number}
default:
return state;
}
}

注意,reducer是一个纯函数,不需要直接修改state

这样派发action之后,既可以通过store.subscribe监听store的变化,如下:

store.subscribe(() => {
console.log(store.getState());
})

小结

  • createStore可以帮助创建 store
  • store.dispatch 帮助派发 action , action 会传递给 store
  • store.getState 这个方法可以帮助获取 store 里边所有的数据内容
  • store.subscrible 方法订阅 store 的改变,只要 store 发生改变, store.subscrible 这个函数接收的这个回调函数就会被执行

在React项目中,会搭配react-redux进行使用

何为react-redux?

如下图

在react-redux中,我们将UI组件去除掉redux的操作,将redux的操作全部放在容器组件身上

容器组件向redux进行数据获取和更改,通过props将数据传递给UI组件,UI组件也通过props告知容器组件要对redux中的数据进行何样的操作

容器组件用以专门向reduxi请求修改状态,存在containers文件夹里面

UI组件无法向redux去修改,存在component文件夹里面

connet是一个函数,这个函数调用的返回值依旧是一个函数 ,返回值的函数让容器组件与UI组件进行关联,从而通过props进行组件间的通信。

const CountContainer=connect()(CountUI)

connect在第一次调用的时候要传入两个参数,传入的两个参数必须是函数 一个是redux中所保存的状态,另一个就是操作状态的方法。简写如下

function a(){
return {n:900}
} function b(){
return {jia:(num)=>{dispatch({
  type: "ADD_NUMBER",
number: 5
})}}
} export default connect(a,b)(CountUI)

a函数返回的对象key作为UI组件的props的key,value作为UI组件的props的value,以供UI组件接收到state

b函数返回的对象实际上向redux派生一个action,告知redux对state中的数据进行何种操作

容器组件的两个方法:mapStateToProps和mapDispatchToProps.

这是官方给的名称,为了好理解上面的代码使用a,b简述。实际使用以官方文档为主

export default connect(mapStateToProps,mapDispatchToProps)(CountUI)

回到今天所学习到的新框架——dva

dva 好像就是redux的一些轻量级应用整合,简化了API,让开发更方便,但果然这是我自己的理解。

核心概念

  • State:一个对象,保存整个应用状态
  • View:React 组件构成的视图层
  • Action:一个对象,描述事件
  • connect 方法:一个函数,绑定 State 到 View
  • dispatch 方法:一个函数,发送 Action 到 State

不难发现,其本质和redux一样,只不过dva让redux的操作更加的方便简洁,提高了我们的开发效率。

Action 是用来描述 UI 层事件的一个对象。

connect 方法返回的也是一个 React 组件,也是称为容器组件。因为它是原始 UI 组件的容器,即在外面包了一层 State。

connect 方法传入的第一个参数是 mapStateToProps 函数,mapStateToProps 函数会返回一个对象,用于建立 State 到 Props 的映射关系。

dispatch 是一个函数方法,用来将 Action 发送给 State。

dispatch 方法从哪里来?被 connect 的 Component 会自动在 props 中拥有 dispatch 方法。

其实dva内容和react-redux是一样的原理,只不过为了开发速度,dva封装的API使得操作redux更为便捷

dva中有model对象,这个对象是我第一次遇到的,在这个对象中,封装这对redux中的各种操作

model最简结构

export default {
namespace: 'count',
state: 0,
reducers: {
add(state) {
return state + 1;
},
},
effects: {
*addAfter1Second(action, { call, put }) {
yield call(delay, 1000);
yield put({ type: 'add' });
},
},
};

Model 对象的属性

  • namespace: 当前 Model 的名称。整个应用的 State,由多个小的 Model 的 State 以 namespace 为 key 合成
  • state: 该 Model 当前的状态。数据保存在这里,直接决定了视图层的输出
  • reducers: Action 处理器,处理同步动作,用来算出最新的 State
  • effects:Action 处理器,处理异步动作

Reducer

Reducer 是 Action 处理器,用来处理同步操作,可以看做是 state 的计算器。它的作用是根据 Action,从上一个 State 算出当前 State。

Effect

Action 处理器,处理异步动作,基于 Redux-saga 实现。Effect 指的是副作用。根据函数式编程,计算以外的操作都属于 Effect,典型的就是 I/O 操作、数据库读写。

Generator 函数

Effect 是一个 Generator 函数,内部使用 yield 关键字,标识每一步的操作(不管是异步或同步)。

call 和 put

dva 提供多个 effect 函数内部的处理函数,比较常用的是 call 和 put

    • call:执行异步函数
    • put:发出一个 Action,类似于 dispatch

我们约定当 src/models 下存在 dva 的 models 文件时,会被自动加载到项目中。 即约定了存在即生效,因此我们约定仅在这个文件夹下存放 dva 的 models 文件,虽然存放其他的文件会被框架自动过滤忽略,但是在这个目录存放其他文件会增加理解的心智负担,建议不要存放无关的文件。且为了管理方便,一般将文件名和 models 的 namespace 一一对应,不仅可以直观的找到相应的 models ,而且能够保证不会存在 models 冲突的问题,因为文件系统本身就不允许同名文件。

时间不早,先休息,后面将会针对dva操作redux的具体进行总结,在这个总结中我们可以很直白的看出dva与redux操作上的简易程度

宣传下自己的网站mishi-blog.com

尚在襁褓中的一个网站。

redux和dva的更多相关文章

  1. Dva & Umi

    Dva & Umi Dva.js & Umi.js React & Redux https://dvajs.com/ React and redux based, lightw ...

  2. Vuex初识

    vuex是vue中单向数据流的一个状态管理模式,它可以集中存储管理应用中所有组件的状态,并且有一套相应的规则可以去预测数据的变化.类似与此的还有react中的redux,dva等状态管理模式. 一般我 ...

  3. JSP等模板引擎已死,大前端为趋势

    我们先来看一下tomcat版本数据: 我们可以看到,从tomcat8之后JSP就再没有新的支持了,tomcat8大概是2013年发布的,也就是说,从2013年开始jsp技术已经实质上不被官方继续维护了 ...

  4. 6. 使用antd pro构建web页面

    前言 在开始之前,希望我们已经掌握了一部分react的知识,由于没有太多经验,其实我也是属于摸索阶段.这里假定我们已经了解了react,redux和dva/umi相关的知识.并有做过相关练习. 如果还 ...

  5. React学习之常用概念

    看见一篇不错的文章转载,文章源地址:https://blog.csdn.net/zwp438123895/article/details/69374940 一.  State和 Props state ...

  6. JS系列:js节点

    节点(node) 在html文档中出现的所有东西都是节点 元素节点(HTML标签) 文本节点(文字内容) 注释节点(注释内容) 文档节点(document) … 每一种类型的节点都会有一些属性区分自己 ...

  7. 测试平台系列(5) 引入Ant Design Pro

    引入Ant Design Pro 回顾 还是继续回顾下之前的作业, 返回的中文变成了ascii字符,不要紧,我们光荣地百度一哈. 随便点进去看看,都可以找到正确答案: 可以看到,我们需要修改confi ...

  8. [开源]React/Vue通用的状态管理框架,不好用你来打我👀

    为了防止被打,有请"燕双鹰"镇楼️‍♀️️‍️‍...o... 话说新冠3年,"状态管理框架"豪杰并起.群雄逐鹿,ReduxToolkit.Mobx.Vuex. ...

  9. Vuex、Flux、Redux、Redux-saga、Dva、MobX

    https://www.jqhtml.com/23003.html 这篇文章试着聊明白这一堆看起来挺复杂的东西.在聊之前,大家要始终记得一句话:一切前端概念,都是纸老虎. 不管是Vue,还是 Reac ...

随机推荐

  1. 隐藏浏览器header中X-Powered-By: PHP信息

    在php程序中,默认会在http请求响应头中输出php版本信息.如下: HTTP/1.1 200 OK Content-Type: text/html; charset=utf-8 Date: Tue ...

  2. 关于Spring中的useSuffixPatternMatch

    背景 spring-boot的版本是2.1.4.RELEASE,spring的版本是5.1.6.RELEASE 一个例子如下: @Configuration @Import(WebMvcAutoCon ...

  3. data:image字符转byte[]

    var data = "data:image/bmp;base64,Qk3aHwAAAAAAADYAAAAoAAAAZAAAABsAAAABABgAAAAAAKQfAAAAAQAAAAEAA ...

  4. 抽象数据类型(ADT)

    抽象数据类型(Abstract Data Type,ADT)是指一个数学模型以及定义在这个模型上的一组操作.抽象数据类型的定义仅仅取决于它的一组逻辑特性,而与它在计算机中的表示和实现无关. 例如,in ...

  5. Python数据分析--Numpy常用函数介绍(3)

    摘要:先汇总相关股票价格,然后有选择地对其分类,再计算移动均线.布林线等. 一.汇总数据 汇总整个交易周中从周一到周五的所有数据(包括日期.开盘价.最高价.最低价.收盘价,成交量等),由于我们的数据是 ...

  6. jQuery基础入门+购物车案例详解

    jQuery是一个快速.简洁的JavaScript代码库(或JavaScript框架).jQuery设计的宗旨是"write Less,Do More",即倡导写更少的代码,做更多 ...

  7. conda和pip加速参考

    conda install和创建虚拟环境下载慢,可以修改/root/.condarc文件: vim /root/.condarc 各系统都可以通过修改用户目录下的 .condarc 文件.Window ...

  8. node环境下怎样优化引入多文件(实现自动化)

    const mocks = [];function getJsonFiles(jsonPath) {function findJsonFile(path) {let files = fs.readdi ...

  9. RPA应用场景-自动轮询汇总报表

    场景概述 自动轮询汇总报表 所涉系统名称 券商披露网站 人工操作(时间/次) 36小时 所涉人工数量 1 操作频率 每月 场景流程 1.每月初机器人自动登录网站轮询36家券商披露的财务报告,并下载 2 ...

  10. 数仓的字符截取三胞胎:substrb、substr、substring

    摘要:下面就来给大家介绍这三个函数在字符截取时的一些用法与区别. 本文分享自华为云社区<GaussDB(DWS)中的字符截取三胞胎>,作者:我站在北方的天空下 . 在GaussDB(DWS ...