关于dva框架的二三事

发布时间:2018-06-24 15:31,

浏览次数:618

, 标签:

dva

前言

我开通了一个微信公共号“王和阳的航海日志”,在上面记录着自己的学习、思考、实践和成长的过程,欢迎关注、交流和拍砖。

最近在项目里用了DVA,一个基于Redux的前端应用开发框架,用dva能让我们省去配置项目的一堆麻烦事儿。关于Dva的使用和介绍这里就不多说了,官方文档已经讲得很详细了。下面简单结合我自己的实践经历,讲讲DVA的一些思想以及一些关于数据流向的想法。

Dva的框架和由来

一图胜前言,首先我们看下传统的React项目的组件结构是怎么样的:

如果和想要发生联系,则只能通过父组件

来实现,这个方式在页面比较简单的时候还能够胜任,但若项目复杂起来之后,整个页面的数据流向就会变得如下图所示:

在这种情况下对项目进行维护绝对是个灾难,同时对这样的项目进行改动也是很困难的事儿,因为不同组件之间耦合的地方太多了,所以我们需要对state

做额外的管理,于是我们就使用了Redux,那么项目结构就变成了这样:

可以看到这已经把state和处理逻辑从 里面抽取出来了, 原先的add和finish操作也变成了reducer里的函数。因为 及

都是 Pure Component

, 那么通过 connect

方法使这些组件建立起与store 的联系,同时通过 dispatch 向 store 发送 action, 促发 store 的状态进行变化, 一旦状态有变,

因为组件和store是被 connect,那么组件也就会随之更新,而且这个过程是可以被拦截的,所以我们就可以很方便地增加各种 Middleware

,从而实现各种自定义功能, 例如log、高阶组件,并且这样的结构耦合度更低, 复用度更高, 扩展性更好。

需要注意的是,上面的项目结构其实是不包含异步处理的,则为了处理异步请求,我们引入了redux-sage

,redux-saga

会拦截异步action并发起http请求,以发送type=add的异步action网络请求来说,若请求成功,则继续发送一个type=addSuccess的

action,若请求失败,则发送一个type=addFail的action。

在了解了上面这些概念后,使用了dva后项目的结构也就呼之欲出了:

dva本身就是React + Redux + saga的组合,而图中红框的部分就是dva,可以很清楚地看到,dva把store和saga

结合成了一个model,同时增加了一个subscription来订阅其他来源的action(例如键盘操作、路由变化)

下面简单总结下dva中的一些概念以及自己的一些思考

state

state 表示 Model 的状态数据,通常表现为一个 javascript

对象(当然它可以是任何值),且需要把这个state当做不可变数据(immutable

data)来处理,保证每次得到的state都是全新对象,新旧对象间不存在引用关系,在检测两个state

里的复杂对象时只需要比较其属性的引用即可,这样做的好处是能够提升性能,便于测试和追踪变化(可用来实现神奇又好玩的时光机穿梭神器redux-devtool

)。具体到代码里就如下图所示:

state: { keyword: '', moduleList: [], }, ..... return { ...state, keyword };

action 和 dispatch

action 是改变 state 的唯一途径,是一个普通的 javascript 对象,它描述了一个行为且是改变 state

的唯一途径。从用户UI操作事件、网络请求回调和 WebSocket 等其他地方获得的数据,最终都会通过dispatch 函数调用一个 action

,从而改变对应的数据。action 必须带有 type 指明具体的行为名称,且能附带上额外的信息。

dispatching 是一个用于触发 action 的函数,且 dispatch 是在组件 connect Models以后,才能通过 props 传入。

action和dispath存在的意义就在于将“如何改变数据”和“改变数据”这两件事分开进行,让我们对如何改变state有更清晰的思路。

dispatch({ type: 'add', payload:{ item:'a' } });

reducer

reducer 是描述如何改变数据的,它接受两个参数(之前已经累积运算的结果和当前要被累积的值),并返回一个新的累积结果。

通过 actions 中传入的值,与当前 reducers 中的值进行运算获得新的值(也就是新的 state)。需要注意的是 Reducer 必须是纯函数

,即同样的输入必然得到同样的输出,它们不应该产生任何副作用,或者用更加专业的话说,这个函数是幂等的。

effect

effect

被称为副作用,在我们的应用中,最常见的就是异步操作(例如网络请求)。它来自于函数式编程的概念,之所以叫副作用是因为同样的输入不一定获得同样的输出。现在函数式编程大行其道的原因主要有以下两点:

* 函数式编程是面向数学的抽象,更加符合人的思维逻辑

* 函数是引用透明且没有副作用,不依赖外部的状态也不改变外部的状态。

* 因为函数是不可变的,则由于多个线程之间不共享状态,不会造成资源争用(Race condition),也就不需要用锁

来保护可变状态,也就不会出现死锁,这样可以更好地进行并发,尤其是在对称多处理器(SMP)架构下能够更好地利用多个核提供的并行处理能力。要知道现在计算机的计算能力的增加已经不是依靠主频频率的提升,而是更依赖于CPU核心个数的增加,这一点带来的好处是母庸置疑的

5 。

(如果你想了解更多关于函数式编程的信息,可以阅读JS函数式编程指南

。)

dva 为了控制副作用的操作,引入了redux-sagas

做异步流程控制,且因为采用了generator的相关概念

,所以能将异步转成同步写法,从而将effects转为纯函数。

effects: { * createModule({ payload: { formData} }, { call, put }) { const

result =yield call(Services.createModule, formData); if (result) { yield put({

type:'startSearch'}); } } }

subscription

subscriptions 是一种从 源 获取数据的方法,它来自于 elm。

Subscription 用于订阅一个数据源,然后根据条件 dispatch需要的action。数据源可以是服务器的 websocket

连接、keyboard 输入、geolocation 变化、history 路由变化等等。

app.model({ namespace: 'count', subscriptions: { setup({ dispatch, history })

{return history.listen(({ pathname }) => { // 第1次进入页面,请求模块数据 if (pathname ===

'/module') { dispatch({ type: 'startSearch'}); } }); }, } });

简短的完整代码

import dva, { connect } from 'dva'; import { Router, Route } from 'dva/router'

; import React from'react'; import styles from './index.less'; import key from

'keymaster'; const app = dva(); app.model({ namespace: 'count', state: { record:

0, current: 0, }, reducers: { add(state) { const newCurrent = state.current + 1;

return { ...state, record: newCurrent > state.record ? newCurrent :

state.record, current: newCurrent, }; }, minus(state) {return { ...state,

current: state.current -1}; }, }, effects: { *add(action, { call, put }) { yield

call(delay,1000); yield put({ type: 'minus' }); }, }, subscriptions: {

keyboardWatcher({ dispatch }) { key('⌘+up, ctrl+up', () => { dispatch({type:

'add'}) }); }, }, }); const CountApp = ({count, dispatch}) => { return (

className={styles.normal}>

Highest Record:

{count.record}

{count.current}

className={styles.button}> { dispatch({type:

'count/add'}); }}>+

); }; function

mapStateToProps(state) { return { count: state.count }; } const HomePage =

connect(mapStateToProps)(CountApp); app.router(({history}) =>

{history}>

);

app.start('#root'); // --------- // Helpers function delay(timeout){ return new

Promise(resolve => { setTimeout(resolve, timeout); }); }

引用

* dva图解

* dva介绍

* redux调试神器之redux-devtools

* immutable data

* redux-sagas

* 什么是函数式编程思维?

dva处理_关于dva框架的二三事相关推荐

  1. 关于dva框架的二三事

    前言 我开通了一个微信公共号"王和阳的航海日志",在上面记录着自己的学习.思考.实践和成长的过程,欢迎关注.交流和拍砖. 最近在项目里用了DVA,一个基于Redux的前端应用开发框 ...

  2. dva是什么游戏_守望dva下载_守望dva大全_手游排行榜_网游/单机游戏_九游

    [详情] ◇ The D.VA Pong é um jogo retro do Pong numa versão atualizada e individual com o contexto da p ...

  3. chrome 插件 页面请求转发_巧用Chrome插件二三事

    作为程序员,在日常工作中往往会遇到一些影响工作效率的事情,比如:配套工具不趁手,开发环境难以搭建,代码调试困难等.这些问题由于并不直接与产品相关,所以往往受到忽视,但它们却又无时无刻不在,确确实实地影 ...

  4. dva的用法_使用 dva 构建小型前端项目 (一)

    前言 去年11月的时候接手了一个小型的后台系统,负责前端开发,团队经过研究选择了从来没有用过的 Ant Design,作为一门设计语言(什么是设计语言),如果我们此次项目使用 Ant Design 获 ...

  5. React+ Dva + Atd入门知识(必读)——框架详解

    学react是会有很多疑惑, 不知道需要用到ES6的哪些知识点: react component 有三种写法,都要掌握还是 .... JavaScript语言 变量声明 const 和 let 不要用 ...

  6. PyTorch框架学习二十——模型微调(Finetune)

    PyTorch框架学习二十--模型微调(Finetune) 一.Transfer Learning:迁移学习 二.Model Finetune:模型的迁移学习 三.看个例子:用ResNet18预训练模 ...

  7. Android驱动学习-内部机制_回顾binder框架关键点

    内部机制_回顾binder框架关键点 server注册服务时, 对每个服务都提供不同的ptr/cookie, 在驱动程序里对每个服务都构造一个binder_node, 它也含有ptr/cookie c ...

  8. Konstrukt PHP REST框架 教程二

    Konstrukt PHP REST框架 教程二 入门 - 第2部分 在本教程中,我们假设你已经完成了第一个教程,因为它的基础上产生的代码从该. 谈判的Content-Type 在大多数情况下会发出一 ...

  9. “Zhuang.Data”轻型数据库访问框架(二)框架的入口DbAccessor对象

    目录: "Zhuang.Data"轻型数据库访问框架(一)开篇介绍 "Zhuang.Data"轻型数据库访问框架(二)框架的入口DbAccessor对象 先来看 ...

最新文章

  1. python3的各个版本有什么区别_python不同版本的_new_不同点总结
  2. 十个最值得阅读学习的C开源项目代码
  3. 浅谈Python Web的五大框架
  4. TalkingData:2014年移动打车应用行业报告
  5. AJAX(一)XMLHttpRequest
  6. 用XCA(X Certificate and key management)可视化程序管理SSL 证书(2)--生成SSL证书请求...
  7. 哪些年我们不曾的考虑。。。
  8. java基础(十一) 枚举类型
  9. 快速解读linq语法
  10. 《MySQL——join语句优化tips》
  11. VDO-SLAM论文阅读
  12. RSync服务器配置
  13. python的框架django_Python框架Django高级内容,python
  14. Javascript深入理解构造函数和原型对象
  15. Php程序监控邮件提醒linux,Linux ping命令实现网络监控 并邮件提醒管理员
  16. Unity3D button控件
  17. 【板栗糖GIS】arcmap—如何通过影像融合提高遥感数据的分辨率
  18. 给大家讲解一下 AIDL原理分析
  19. form表单提交的方法
  20. TYUT太原理工大学2022数据库考试题型大纲

热门文章

  1. 推荐一个220V控制12V的电路板继电器-220v降压控制继电器
  2. python头像教程_微信好友头像全家福详细教程python版
  3. 都说程序员越老越“不值钱”,想避免未来也“被优化”,怎么办?
  4. 软件工程面向对象分析
  5. IT去中心化背后的低代码平台
  6. 【超详细】MySQL零基础入门实战
  7. 中小学在线学习云平台最新社区版 自适应手机端 ASP v1.0
  8. 解救MacBook Pro老电脑显卡
  9. python提取发票信息发票识别_分享一个电子发票信息提取工具(Python)
  10. 管理安装软件包yum什么是yum