Open sorrycc opened 8 years ago
我觉得这个做法非常适合websocket,但是如果没有websocket,是不是没有必要事先存好所有id?因为最新数据都是需要直接得到的而不是通过websocket返回最新的数据的id然后通过id找到相应的值。现在非常纠结dva项目架构该怎么写比较好
你指的是 state 怎么设计?
model设计费脑子,体现在什么地方? 初学者不太懂,但是感觉到state要弄好是不太容易的,这里有什么教程,或者经验吗?
假如我要删除一条数据的话 怎么删
@jiaozhouzhou 删掉之后刷新列表?
云歉,model里面的selectors是干嘛用的?是因为跳转页面以后,保持状态有关系吗?
我感觉这个说明比user-dashboard那个项目清晰的多,另外似乎还要学redux-saga,真是头大啊
@HelloSkull 不用学习完整的 redux-saga,掌握这里的知识点就可以用 dva 了,https://github.com/dvajs/dva-knowledgemap
Live Demo
说一说基于 dva 实现 dva-hackernews 的过程。
基本思路是按照 service -> model -> component 的顺序来实现的,好处是可以用真实数据,不用额外写 mock 方法。
脚手架
通过 dva-cli 生成项目初始文件,然后
npm start
启动。Service
hackernews 数据接口来自 firebase,所以可以直接用 firebase 这个 package 。firebase 基于 websocket 连接实现,除了初次请求慢些,后面的数据加载很快。相比 http 来说,省去不少请求。
为了方便在 effects 里调用,service 方法需要返回 promise 。
watchList
除外,这个不在 effects 里调,而是在 subscriptions 里,用于实时更新列表数据。Model
写 model 层是脑力劳动,而写 component 层是体力劳动。
数据结构
先设计数据结构,为了让 reducer 里写得比较容易,所以选择扁平化的方式。即把 item 拎出来,以 id 为 key 统一存放,然后其他地方即可引用 id 。
这样更新 item 就比较简单,反之如果要更新 list.top['123'] 的数据,想想都麻烦。(没用 immutable.js)
state 更新
然后是完成处理 action 的部分,reducers 和 effects,分别负责 state 更新和异步逻辑。
state 更新的部分写在 reducers 里,没什么特别的,灵活掌握 array 和 object 的各种方法就可以了,注意 array 到 object 的转换可以用 reduce 简化。
异步逻辑
异步逻辑部分,写在 effects 里。通过 generator 组织,所以基本上都是一层缩进下来就完了。
为了实时性,切换页面不管 item 是否有缓存,都会重新请求一遍。
评论数据是递归获取的,因为不知道有几层。还好是 websocket,如果换成 http 的实现应该会很慢。虽然是比较快,但在评论页面也能明显感觉到是一层层更新出来的。
定义完所有 action 的处理,接下来要看如何调用他们。基本上就两个地方,subscriptions 和 component 。
初始数据请求
subscription 意为订阅,用于数据源的订阅。
而初始数据加载实际上是订阅了 history 的变更,待满足 url 匹配时,触发 action 加载远程数据。这些逻辑不放 route component 还有好处是可以更好地配合 hmr,同时让 route component 保持 stateless component 的写法。
由于 react-router 的限制,这里需使用 path-to-regexp 库来解决 url 匹配的问题。
当用户进入 item 页面时,通过 action
item/fetchComments
获取评论数据。实时更新
同上,实时更新也写在 subscriptions 里,等于是订阅了 list 的数据源。有更新时,保存新的 id,然后重新加载本页数据。
selector
由于我们的数据是扁平化的,不能直接交由 component 渲染,需要一层 selector 。比如我想要 top 下第 1 页的列表。
Component
写完 model 层,感到一阵轻松,剩下的基本不费脑了。
动画
动画没有用上 react-motion,而是基于 ReactCSSTransitionGroup 实现,方法和 vue 以及 angular 都类似。动效可以上 nganimate 找一个喜欢的样式过来用。
总结
以上是实现 hackernews 一些经验。先写什么并不重要,主要是要有分层的概念,可以先写 model,也可以先写 component 。dva 借鉴 elm 的概念整合了 reducers, effects 和 subscriptions 到 model,让分层更清晰,并让各种觉得的代码有所归属。希望大家能动手实践一把,会发现相比现有 redux 方法的优势。
More