欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

flux架构中什么数据才应该放store?

程序员文章站 2022-06-21 22:31:00
flux架构中什么数据才应该放store? flux的机制已经有太多文章写过了,这里就不再多说。 Redux在这方面就做得很棒,它的store只有一个,并且引入了immutab...

flux架构中什么数据才应该放store?

flux的机制已经有太多文章写过了,这里就不再多说。

Redux在这方面就做得很棒,它的store只有一个,并且引入了immutable的概念,使得store的可预测性更进一步。但是它的异步操作是痛点,虽然有如saga这种优秀的中间件,但对于新手来说,还是很容易绕晕。

vuex这方面做得挺不错,它把异步操作限定在了actions阶段,减少了很多繁琐步骤。它的store也是唯一,但你可以在任何地方用this.$store去引用,方便的同时,对习惯不好的同学,也会带来一些隐患。

好了,接下来我们该进入主题了。

多方观点

总结起来,目前主流的观点有两种:

store只存放公共数据,组件的数据、状态自行维护。

所有数据都应走store,view层只管展现数据,这也是flux官方所推荐的做法。

这里特别强调一下,本文所探讨的是SPA(单页)应用。所以,如无特殊说明,这里指的组件,特指页面级组件,或者说路由级组件,并非单组件。另外,flux官方并无数据的概念,所有数据均是状态。那我为什么要特意抽出来呢?后面会说。

持观点1的人认为:只有公共的数据、需要跨组件的数据才应放入store。优点是store小,页面组件内的数据不必绕来绕去,开发简单。

持观点2的人认为:呃,貌似我自己也差不多这种思想,为免带入个人思想,这里就不妄自猜度他人想法了。

store定位

目前各方都有一定的支持人数,那么,要理清这个问题,我们就得先把store的角色定位好。是做为数据中心呢?还是做为全局变量仓库?或者还有另外的想法?

自从接触flux以来,我也一直遵循第二种思路,但又不完全是。store是什么?从字面上理解,就是一份存储,一份放在本地的存储。再来看一下我们目前的前后端交互,拉取 => 展现,再拉取 => 再展现。每切换一次页面,都要再拉取一次数据。我们为什么不能做到更好呢?把store定位为一份服务器数据本地快照如何?没错,这就是我的思路。

传统应用开发,我们的应用程序都是直接和数据库交互的。但前端不行,抛开还需要后端程序提供接口不说,前端与数据库中间还隔着http这层,这就产生了巨大的延时。所以,为什么我们不能在本地建立一份数据快照?用store来做这事是不是合适?

也许你会说,localStorage、indexDB来做这事才更合适。localStorage大小且不说,你还需要借助JSON来进行数据维护。而indexDB,操作起来也并不简便。并且,他们的存取速度与store也明显不是一个级别(虽然用户几乎感觉不到差异)。

方案

除类似autocomplate这类的sideways数据,所有从后端拉取的数据,以页面级组件为单位,都存入store,做为服务器数据本地快照。这样,当用户切换页面时,只有view会被销毁。每次用户进入该页面,首先会拿到一份快照数据,store同时向服务器查询最新数据。如有更新,可做提示有新数据(如新浪微博)。

而对于状态(对,前面说了我把数据和状态分别开来对待。数据指业务数据,而状态,我理解为行为状态),除非是全局状态,否则,管你是页面级组件还是单组件,自个儿内部维护。

特别说明,store里的数据,应当尽量保持是原始的服务器数据快照,而不应该去做任何mutate,类似Redux的immutable思想。而对于add、del之类操作的结果,也不应当放入store,而只是一种状态反馈,应当在组件内部消化。

这样,我们的store里就只有纯粹的两种东西:全局状态和业务数据(服务器数据快照)。

更进一步,我们还可以借助本地存储把store做为本地缓存,达到重启app可立即恢复现场的效果。

优点

1.用户体验,对于切换频率高的页面,用户体验直线上升。设想一下,如果数据放到页面组件内部,离开当前页数据即被销毁,当用户一秒后再次返回该页。。。

2.资源优化,减少对服务器的请求,对于更新周期长的数据,例如用户个人信息,完全可以仅请求一次

3.可预测性,flux所提倡的数据可预测成为可能,各种数据追踪工具得以大展身手(微信小程序开发工具的数据追踪就挺不错)

4.可读性,component只有view逻辑,不掺杂modal逻辑,业务逻辑清晰易维护

5.扩展性强,例如需要加入权限控制,进行数据过滤,在store层面就可以轻松解决。而如果业务数据在组件内部。。。

6.统一性,所有业务数据统一存取,管理方便。

缺点

再来看看持观点1的人所反对的:

1.store庞大,持观点1的人首先反对的就是这个。但是,对于SPA来说,对于现代PC来说,你的SPA的store能达到以G为单位不?

2.编写繁琐,嗯,这算一个理由吧。不过,对于其所带来的优点来说,这点牺牲并不算什么吧?

3.数据时效,有人提到,一次性数据(比如订单结算)不应被放入store。没错,这点我们可以在页面destory时手动清理不是么?

4.单store文件难维护,有人提到,所有业务数据操作都在store里,难维护。其实利用现在的构建工具,我们已经可以做到把各个页面组件的store单独切出来,构建时再合并,这并不会影响可维护性。

5.数据污染,有人担心,这么多数据放到store里,会不会造成污染。对于这点,无论Redux和vuex,都是支持子store的。也就是命名空间的概念。比如 store.pageModule1、store.pageModule2。再配合一些测试工具(如mocha)做重名检测,这方面完全不是问题。

还有什么

实际开发过程中,还有一个经常遇到的,经常被人问起的问题:公共页面组件容易加载到非自身数据。比如文章详情页,如果先浏览了文章1,再浏览文章2,有可能先显示文章1的内容,会很怪异。其实这也是一个很容易解决的问题,进入一个页面组件时,首先加载的其实是initialState,紧接着,flux才把store里的数据推过来。这个时候,你应该做文章id校验,只有是自身数据,才assign。

适用场景

记得有人说过这样的话:“如果你不知道该不该用flux,那说明你并不需要它。” Redux的作者 Dan Abramov 说:“Flux 架构就像眼镜:您自会知道什么时候需要它。” 如果你的业务只是需要一个全局变量仓库,flux会不会过重?而对于大多数SPA场景,我想这个思路都是行得通的。另外,对于一次性数据比较多的应用,那这种思路或许也不太适合。

响应式store设想

我觉得最理想的状态,flux架构还可以更进一步,把store做得更纯粹一些,可以自行维护数据。具体做法是,ajax放到store层面,当请求的数据不存在或过旧时,自动拉取,而不需要通过actions来处理拉取数据的逻辑。