Redux对决MobX,谁更适合JavaScript项目?
对于很多JavaScript开发人员和程序员来说,对Redux最大的不满是实现功能所需的样板代码数量。而MobX可能是一个更好的选择,它提供类似的功能,但代码更少。
本文的目的是帮助JavaScript开发人员或程序员决定这两种状态管理解决方案中哪一种最适合你的项目。本文已将此CRUD Redux项目迁移到MobX以作为本文中的示例。那么首先讨论使用MobX的优缺点,然后将演示两个版本的实际代码示例来显示差异。
本文中提到的项目的代码可以在GitHub上找到:
Redux CRUD示例:https://github.com/sitepoint-editors/redux-crud-example
MobX CRUD示例:https://github.com/sitepoint-editors/mobx-crud-example
Redux和MobX有什么作用?
首先,我们来看看它们有什么共同点:
是开源库
提供客户端状态管理
通过redux-devtools扩展支持时差调试
没有绑定到一个具体的框架
广泛支持React/React Native框架
使用MobX的4个理由
现在来看看Redux和MobX之间的主要区别。
1.易于学习和使用
对于初学者,可以在短短30分钟内了解如何使用MobX。一旦了解了基础知识,你不需要学习任何新的东西。Redux的基础也很简单。但是,一旦开始构建更复杂的应用程序,将必须处理:
使用redux-thunk处理异步操作
使用redux-saga简化代码
定义选择器来处理计算值等
使用MobX,所有这些情况都会被照顾到。不需要额外的库来处理这种情况。
2.少写代码
要在Redux中实现功能,需要至少更新四个组件。这包括编写reducer,actions,容器和组件的代码。如果正在开展一个小型项目,将特别烦人。MobX只需要更新至少2个(即store和视图组件)。
3.全面支持面向对象编程
如果你喜欢编写面向对象的代码,那么你将很高兴的知道可以使用OOP来实现MobX的状态管理逻辑。通过使用诸如@observable和@observer之类的装饰器,可以轻松地将纯JavaScript组件存储起来。如果你喜欢功能编程,也没问题,这也是支持的。另一方面,Redux则致力于功能规划原则。但是,如果需要基于类的方法,可以使用redux-connect-decorator库。
4.处理嵌套数据很容易
在大多数JavaScript应用程序中,你将发现自己正在使用关系或嵌套数据。为了能够在Redux store中使用它,你必须首先对它进行规范化。接下来,必须编写更多的代码来管理标准化数据中的引用跟踪。
在MobX中,建议以非规范化形式存储数据。MobX可以跟踪你的关系,并会自动重新呈现更改。通过使用域对象来存储数据,可以直接引用其他store中定义的其他域对象。另外,可以使用(@)计算的修饰符和可修改程序来轻松解决复杂的数据挑战。
不使用MobX的3个理由
1.太多的自由
Redux是一个框架,为编写状态代码提供严格的指导。这意味着你可以轻松编写测试并开发可维护的代码。MobX是一个库,没有关于如何实现它的规则。这样做的危险在于,很容易采取快捷方式并应用快速修复,这可能导致不可维护的代码。
2.很难调试
MobX的内部代码处理了很多逻辑,使你的应用程序反应。在不可见的区域,你的数据在store和组件之间传递,这使得当你遇到问题时很难进行调试。如果你直接在组件中更改状态,而不使用@actions,你将很难精确定位错误的来源。
3.可能会有一个更好的替代MobX
在软件开发中,新出现的趋势一直呈现。目前,有几种解决方案与Redux和Mobx竞争。几个例子是Relay/Apollo&GraphQL,Alt.js和Jumperuit。任何这些技术都有潜力成为最受欢迎的。如果哪一个最适合你,那么你必须尝试一下。
代码比较:Redux vs MobX
说了一大堆理论,让我们看看代码。首先,我们比较每个版本的引导。
引导
Redux版本:
在Redux,首先定义store,然后我们通过Provider传递给应用程序。我们还需要定义redux-thunk和redux-promise-middleware来处理异步功能。redux-devtools-extension允许我们在time-traveling mode模式下调试我们的store。
MobX版本:
在MobX中,我们需要设置多个store。在这种情况下,只使用一个我已经放在名为allStores集合中的store。然后,Provider将store收藏传递给应用程序。
如前所述,MobX不需要外部库来处理异步操作,因此行数少。但是,我们需要将mobx-remotedev连接到redux-devtools-extension调试工具。
这两个版本中的代码量大致相同。 MobX有较少的导入语句。
Props注入
Redux版本:
在Redux中,使用react-redux的connect()函数将状态和动作传递给Props。
MobX版本:
在MobX中,我们只需注入store集合。我们在容器或组件类的顶部使用@inject来执行此操作。这使得store在Props中可用,这又使我们能够访问特定store并将其传递给子组件。通过存储对象中的属性访问状态和actions,因此不需要像Redux中的情况那样单独通过它们。
MobX版本似乎更容易阅读。 但是,我们可以使用redux-connect-decorators来简化Redux代码。在这种情况下,二者孰优孰劣很难区分。
定义stores, actions,和reducers
为了保持本文精益求精,我将向你显示一个代码示例,只需一个操作。
Redux版本:
在Redux中,我们需要定义actions和reducers。
MobX版本:
在MobX中,action和reducer的逻辑在一个类中完成。我已经定义了一个异步操作,它调用在收到response后的另一个操作entities fetched。
由于MobX使用OOP风格,因此在此处定义的Store类已被重构,以允许使用类构造函数轻松创建多个存储。 因此,这里演示的代码是不绑定到特定域存储的基础代码。
相信与否,两个版本中定义的逻辑都执行相同的任务,即:
更新UI加载状态
异步获取数据
捕捉异常和更新状态
在Redux中,我们使用了33行代码。在MobX中,我们使用了大约14行代码来实现相同的结果!MobX版本的主要优点是可以在几乎所有的域存储类中重新使用基本代码,而且几乎没有修改。这意味着可以更快地构建应用程序。
其他差异
要在Redux中创建表单,我使用了redux-form。在MobX中,我使用了mobx-react-form。这两个库都是成熟的,可以帮助你轻松处理表单逻辑。就我个人而言,我更喜欢mobx-react-form,因为它允许你通过插件验证字段。使用redux-form,可以编写自己的验证码,也可以导入验证包来处理验证。
MobX的一个微小缺点是,你不能直接访问可观察对象中的某些功能,因为它们不是纯粹的JavaScript对象。幸运的是,他们提供了函数toJS(),可以使用它将可观察对象转换为纯JavaScript对象。
结论
显然,你可以看到MobX的代码更加精简。使用OOP风格和良好的开发实践,可以快速构建应用程序。主要的缺点是极易产生不可调试和维护的代码。
另一方面,Redux更受欢迎,非常适合建造大型复杂项目。它是一个严格的框架,具有保障措施,确保每个开发人员和程序员编写易于测试和维护的代码。但是,它并不适合小型项目。
尽管MobX有缺点,如果你遵循良好做法,仍然可以构建大型项目。通过以上的内容来明确是否迁移到MobX或者继续使用Redux,可能还不够。最终,决定取决于你正在开展的项目类型以及可用的资源。
本文由云智小号君编译于sitepoint,原文作者:Michael Wanyoike