-
Notifications
You must be signed in to change notification settings - Fork 324
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
从 0 开始实现 react 版本的 hackernews (基于 dva) #9
Comments
我觉得这个做法非常适合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
The text was updated successfully, but these errors were encountered: