以下内容将结合官方提供的例子:user-dashboard进行讲解,请先行下载运行~
餐厅点餐的比喻
这里引用之前一位同学的比喻,如果把 dva 比喻成一个餐馆,事情就比较好理解。
假设 dva 是一个餐馆,State 是餐馆里面的一道道佳肴,那么会发生下图的故事:
客户到餐馆,先看一下餐牌,选好菜之后,就让服务员给到菜厨房做菜,厨房做好菜之后,就发菜送到客户桌上。
结合两张图来看看(第二张是官网给出的数据流向的解释图)
图二几个概念的类比如下:
- State —— 佳肴
- Route Component —— 客户
- Model —— 厨房 & 餐牌
- Action —— 点菜
- connect —— 这个就是做好菜后,服务员知道这道菜要送给哪个客户的关键
这里 Model 有点特别,既是厨房又是餐牌,程序是自己写的,要想知道有什么“菜”,可以查看每个 model 中定义了什么,当然如果有文档的话就更佳。
dva 的数据流向非常清晰简单,刚开始用可能会觉得有点绕,但慢慢上手之后就会发现这样的分类在编码时很方便。
拿 ant-design-pro,核心的三个文件夹是 models、pages、services
models,承当定义各个模块的数据、处理各个模块的数据、请求异步数据的作用。在我们上面的比喻中就是餐厅的餐牌本以及餐厅。 pages,各个页面、各个功能模块,使用数据的主要地方。 services,只是用于定义接口,没其他作用。
过程中很多步骤都被 dva 封装起来了,我们程序员只需要在 models 中定义,在 pages 中使用即可。
Action 和 connect
Model就不详细讲,详细内容请见:假期充电 Day 4 —— Dva 入门课之Model闲聊
Action 跟 Redux 中的概念是一样的(Dva 可以理解成 Redux 的一个高度好用封装版),State 不能直接修改,只能通过触发 Action 来修改(在下的理解是为了保持数据流的单一性),Action通常由 dispatch 函数触发,所以在使用 dva 中会经常看到如下代码:
dispatch({
type: 'user/add', // user 是命名空间,add是该命名空间下的函数(可能是Reducer也能是Effect)
payload: {}, // 需要传递的信息
});
以上代码意思就是触发 user 命名空间下的 add 方法来达到修改特定 State 的目的。
而 connect 是一个高阶函数,高阶函数的解释详细见 【第1448期】深入理解 React 高阶组件
connect的主要作用是将 Model 中定义的 State 关联到页面中,实际上是以高阶函数的形式注入到该页面的 props 中。
需要注意的是,有些地方用 ES5 的写法,有些地方用 ES7的写法,本质上是一样的,只是写法不同。
Effect
最后讲一下 Effect 吧
我们结合文章开头提到的例子来谈谈,点开这个链接,你会看到 *remove({ payload: id }, { call, put })
,
effects对象中定的函数都用Generator函数,的写法。每个函数都有两个参数 *remove({ payload: id }, { call, put })
,注意,这里用了函数参数的解构赋值的写法
第一个参数,实际上就是 dispatch 的参数,即:
dispatch({
type: 'users/remove',
payload: id,
});
中的这个对象:
{
type: 'users/remove',
payload: id,
}
而第二个参数结构出来的 call, put
是两个函数
call
的作用是异步调用一个后台接口,请求后台数据并返回(ps,这里是以同步的写法写异步函数,下面的代码会等这个异步操作结束后再执行)
put
的作用是触发本 model 内的 effects 函数或者 reducers 函数
好了,今天的内容就到这里,欢迎吐槽和交流~
作者简介:吴勤发,芦苇科技web前端开发工程师。擅长网站建设、公众号开发、微信小程序开发、小游戏、公众号开发,专注于前端框架、服务端渲染、SEO技术、交互设计、图像绘制、数据分析等研究,有兴趣的小伙伴来撩撩我们~ web@talkmoney.cn
访问 www.talkmoney.cn 了解更多