dva处理_关于dva框架的二三事
关于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}>
{count.record}
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框架的二三事相关推荐
- 关于dva框架的二三事
前言 我开通了一个微信公共号"王和阳的航海日志",在上面记录着自己的学习.思考.实践和成长的过程,欢迎关注.交流和拍砖. 最近在项目里用了DVA,一个基于Redux的前端应用开发框 ...
- dva是什么游戏_守望dva下载_守望dva大全_手游排行榜_网游/单机游戏_九游
[详情] ◇ The D.VA Pong é um jogo retro do Pong numa versão atualizada e individual com o contexto da p ...
- chrome 插件 页面请求转发_巧用Chrome插件二三事
作为程序员,在日常工作中往往会遇到一些影响工作效率的事情,比如:配套工具不趁手,开发环境难以搭建,代码调试困难等.这些问题由于并不直接与产品相关,所以往往受到忽视,但它们却又无时无刻不在,确确实实地影 ...
- dva的用法_使用 dva 构建小型前端项目 (一)
前言 去年11月的时候接手了一个小型的后台系统,负责前端开发,团队经过研究选择了从来没有用过的 Ant Design,作为一门设计语言(什么是设计语言),如果我们此次项目使用 Ant Design 获 ...
- React+ Dva + Atd入门知识(必读)——框架详解
学react是会有很多疑惑, 不知道需要用到ES6的哪些知识点: react component 有三种写法,都要掌握还是 .... JavaScript语言 变量声明 const 和 let 不要用 ...
- PyTorch框架学习二十——模型微调(Finetune)
PyTorch框架学习二十--模型微调(Finetune) 一.Transfer Learning:迁移学习 二.Model Finetune:模型的迁移学习 三.看个例子:用ResNet18预训练模 ...
- Android驱动学习-内部机制_回顾binder框架关键点
内部机制_回顾binder框架关键点 server注册服务时, 对每个服务都提供不同的ptr/cookie, 在驱动程序里对每个服务都构造一个binder_node, 它也含有ptr/cookie c ...
- Konstrukt PHP REST框架 教程二
Konstrukt PHP REST框架 教程二 入门 - 第2部分 在本教程中,我们假设你已经完成了第一个教程,因为它的基础上产生的代码从该. 谈判的Content-Type 在大多数情况下会发出一 ...
- “Zhuang.Data”轻型数据库访问框架(二)框架的入口DbAccessor对象
目录: "Zhuang.Data"轻型数据库访问框架(一)开篇介绍 "Zhuang.Data"轻型数据库访问框架(二)框架的入口DbAccessor对象 先来看 ...
最新文章
- python3的各个版本有什么区别_python不同版本的_new_不同点总结
- 十个最值得阅读学习的C开源项目代码
- 浅谈Python Web的五大框架
- TalkingData:2014年移动打车应用行业报告
- AJAX(一)XMLHttpRequest
- 用XCA(X Certificate and key management)可视化程序管理SSL 证书(2)--生成SSL证书请求...
- 哪些年我们不曾的考虑。。。
- java基础(十一) 枚举类型
- 快速解读linq语法
- 《MySQL——join语句优化tips》
- VDO-SLAM论文阅读
- RSync服务器配置
- python的框架django_Python框架Django高级内容,python
- Javascript深入理解构造函数和原型对象
- Php程序监控邮件提醒linux,Linux ping命令实现网络监控 并邮件提醒管理员
- Unity3D button控件
- 【板栗糖GIS】arcmap—如何通过影像融合提高遥感数据的分辨率
- 给大家讲解一下 AIDL原理分析
- form表单提交的方法
- TYUT太原理工大学2022数据库考试题型大纲
热门文章
- 推荐一个220V控制12V的电路板继电器-220v降压控制继电器
- python头像教程_微信好友头像全家福详细教程python版
- 都说程序员越老越“不值钱”,想避免未来也“被优化”,怎么办?
- 软件工程面向对象分析
- IT去中心化背后的低代码平台
- 【超详细】MySQL零基础入门实战
- 中小学在线学习云平台最新社区版 自适应手机端 ASP v1.0
- 解救MacBook Pro老电脑显卡
- python提取发票信息发票识别_分享一个电子发票信息提取工具(Python)
- 管理安装软件包yum什么是yum