我需要怎样的前端状态管理工具?

569 查看

本文从属于笔者的Web前端入门与最佳实践中的前端工程化之状态管理实践系列文章。下面列举了几篇关于Redux与MobX的文章或者讨论,有兴趣的可以阅读下。本文并不是希望安利或者作MobX的布道者,也不是单纯地为了吐槽Functional Programming至上主义,只是笔者提出自己再前端实践中的一些困惑与思考以供批判讨论。

Redux是完全的函数式编程思想践行者(如果你对于Redux还不够理解,可以参考下笔者的深入理解Redux:10个来自专家的Redux实践建议),其核心技术围绕遵循Pure Function的Reducer与遵循Immutable Object的Single State Tree,提供了Extreme Predictability与Extreme Testability,相对应的需要大量的Boilerplate。而MobX则是Less Opinioned,其脱胎于Reactive Programming,其核心思想为Anything that can be derived from the application state, should be derived. Automatically,即避免任何的重复状态。Redux使用了Uniform Single State Tree,而在后端开发中习惯了Object Oriented Programming的笔者不由自主的也想在前端引入Entity,或者说在设计思想上,譬如对于TodoList的增删改查,笔者希望能够包含在某个TodoList对象中,而不需要将所有的操作拆分为Creator、Reducer与Selector三个部分,我只是想简单的展示个列表而已。笔者上大学学的第一节课就是讲OOP,包括后面在C#、Java、Python、PHP等等很多后端领域的实践中,都深受OOP思想的熏陶与灌输。不可否认,可变的状态是软件工程中的万恶之源,但是,OOP对于业务逻辑的描述与代码组织的可读性、可理解性的保证相较于声明式的,略为抽象的FP还是要好一点的。我认可函数式编程的思想成为项目构建组织的不可分割的一部分,但是是否应该在任何项目的任何阶段都先谈编程思想,而后看业务需求?这无疑有点政治正确般的耍流氓了,笔者觉得文本唯一声明秉持的思想就是在不同级别/需求的项目发展的不同阶段我们应该使用不同的技术栈与技术搭配,而本文要讨论的核心即是如何寻求一种尽可能平稳与提供碎片化代码的能够贯彻项目整个生命周期的代码组织或者框架选用方案。

Redux Really Do The Right Thing!Redux Always Do The Best Thing?

Redux的DevTools与Time Travel是如此的优雅与酷炫,再也不用担心应用莫名其妙崩溃而找不到原因,还能方便地同构直出了呢。不过就像笔者在2016年里做前端是怎样一种体验一文中所描述的,我只是想简单的从服务端获取个列表数据然后展示出来,你却告诉我要去学习TypeScript+Webpack+SystemJS+Babel+React+Redux等等,怎么看都还是jQuery的时代简单明了啊。以最基础的添加用户功能来说,在jQuery的时代我们只需要调用Ajax然后等待结果即可,这样当然是有问题的,项目的代码混乱度会随着需求的增加而几何倍数增长。而Redux则以较为严格的规范帮我们实现了Single Responsibility,这样我们至少需要写Reducer、ActionCreator、Store、Selector等等几个文件,当然,在有些最佳实践里会把这几个部分归纳到一个文件中,不过自从笔者发现某个上千行的文件我连看都不想看的时候,觉得还是拆开来好:

然后你需要在需要调用该Action的地方执行以下操作:

笔者最近的两个项目中都使用了Redux作为核心的状态管理工具中,之前是觉得只要有合适的脚手架Webpack-React-Redux-Boilerplate就可以了,不过很多时候看着从Action Creator到Reducer,再到Selector这一系列的仅仅为了实现某个小功能而需要写的N多的Boilerplate,就觉得这并不是我所想要的。就好像现在View层人们经常会讨论对比Vue与React,虽然Redux目前在状态管理领域一骑绝尘,但是也有越来越多的人关注MobX。笔者之前翻译过一篇文章,你并不需要Redux,这是一篇来自Redux作者的对于Redux滥用情况的吐槽。从上面的例子中也可以看出,如果你使用Redux的话,你必须要遵循如下规范:

  • 必须使用基本对象与数组来描述应用状态
  • 必须使用基本的对象来描述系统变化
  • 必须使用纯函数来处理系统中的业务逻辑

而Dan推荐的适用Redux的情况典型的有:

笔者觉得,Redux适合于需要强项目健壮度与多人协调规范的大中型团队,对于很多中小型创业性质,项目需求迭代异常快的团队则往往可能起到适得其反的作用。如果你真的喜欢Redux,那么更应该在合适的项目,合适的阶段去接入Redux,而不是在需求尚未成型之处就花费大量精力搭建复杂的脚手架,说不准客户的需求图纸都画反了呢。

了解下MobX

flow

MobX中核心的概念即是Observable,相信接触过响应式编程的肯定非常熟悉,从后端的典型代表RxJava到Android/iOS开发中的各种响应式框架都各领风骚。这里我们以构建简单的TODOList为例,代码参考了笔者的mobx-react-webpack-boilerplate这个库。首先,以典型的OOP的思想来考虑,我们需要构建ToDo的实体类:

这里@observable注解标注某个变量为被观测值,一旦某个被观测的变量发生了变化,即可以触发观测值相对应的响应。在写好了模型类之后,我们需要编写Store,这里的Store同时包含了数据存储与对数据的操作,和Redux中的Single State Tree差别还是较大的: