一、前言
- 在实际的前端开发中,像 cardList 中包含的那些数据,一般都是通过发起异步 http 请求从后端服务中获得。
- 我们希望把数据逻辑(cardList 相关逻辑)和视图逻辑(PuzzleCardsPage)分开管理在不同的模块中,「关注分离」使得代码更加健壮,同时易于调试。
- 我们希望这些数据在需要的时候,可以提供给不同的组件使用:也即数据共享。
而 dva 就是用来满足这些需求的:
- 通过把状态上提到 dva model 中,我们把数据逻辑从页面中抽离出来。
- 通过 effect 优雅地处理数据生成过程中的副作用,副作用中最常见的就是异步逻辑。
- dva model 中的数据可以注入给任意组件。
- 另外,dva 允许把数据逻辑再拆分(「页面」常常就是分隔的标志),以 namespace 区分。当你觉得有必要时,不同的 namespace 之间的 state 是可以互相访问的。
二、关键对象:model
DVA 的 model 对象有几个基本的属性,需要掌握:
- namespace:model 的命名空间,只能用字符串。一个大型应用可能包含多个 model,通过namespace区分。
- state:当前 model 状态的初始值,表示当前状态。
- reducers:用于处理同步操作,唯一可以修改 state的地方,由 action 触发。reducer 是一个纯函数,它接受当前的 state 及一个 action 对象。action 对象里面可以包含数据体(payload)作为入参,需要返回一个新的 state。
- effects:用于处理异步操作(例如:与服务端交互)和业务逻辑,也是由 action 触发。但是,它不可以修改 state,要通过触发 action 调用 reducer 实现对 state 的间接操作。
- action:是 reducers 及 effects 的触发器,一般是一个对象,形如{ type: ‘add’, payload: todo },通过 type 属性可以匹配到具体某个 reducer 或者 effect,payload 属性则是数据体,用于传送给 reducer 或 effect。
三、初识dva
dva这个数据流解决方法和MVC架构类似:
在models的js中中进行获取后端数据。一定要记得在index.js中配置啊,如果忘记看下面:(route.model(require(’./models/xx’))。
在routers的js中进行数据渲染及业务处理。一定记得在route.js的文件夹下面配置router的访问地址。
提供常用的组件放置在comment中。
四、关于connect
前面知识说了数据渲染、获取后端数据,然而并没有将这两个联系起来。其实用的就是connect。
在此之前先介绍两个东西:
1、mapStateToProps,将需要的state的节点注入到与此视图数据相关的组件上。因为在models的js中我们将数据存贮在state上,现在到了routes的js中,需要使用,就是通过这个方法实现的,从这个方法的名字我们大致也可以看懂的。
function mapStateToProps(state, ownProps) {
return {
loading:state.getIn(['APP', 'loading']),
data:state.getIn(['APP', 'data'])
}
// loading、data都是来自对应的reduce
}
2、mapDispatchToProps,将需要绑定的响应事件注入到组件上。
function mapDispatchToProps(dispatch){
return {
...bindActionCreators(action, dispatch)
}
}
// mapDispatchToProps()函数的bindActionCreators、action需要引入
// import * as action from '../action';
// import { bindActionCreators } from 'redux';
------------------------------------
------------------------------------
// 多个action 引入
import * as action from '../action';
import * as action2 from '../../index/action';
function mapDispatchToProps(dispatch){
return {
...bindActionCreators(action, dispatch),
...bindActionCreators(action2, dispatch)
}
}
------------------------------------
------------------------------------
// 引入一个action里面的多个方法
import { function1, function2, function3 } from '../webs/action'
function mapDispatchToProps(dispatch) {
return {
...bindActionCreators({ afunction1, function2, function3 }, dispatch)
}
}
五、具体案例
待补充。
六、参考博客
七、后记
前端朋友说react简单,好学。对于我是一个新技术,而且我是一个后端,自己给自己无形增加了很大的压力。其实都是没必要的。如果不是工作需要,我估计也不会逼着自己去学,现在回想,其实也没有想象中的那么难懂。按照节奏,先学会用,再去深究原因,不可本末倒置。而且没必要把自己限制在一个后端的框框里面。毕竟纵向发展还是横向发展,亦或是全面发展,究竟哪种好,仁者见仁,智者见智。不过我相信,能完成任务,这是核心,否则一些都是扯淡。