为什么我觉得 MobX 不适合 React

662 阅读2分钟

React 项目的状态管理,主流的有 Redux 和 MobX 两种方案,但相对于 Redux,我觉得 MobX 并不太适合 React。

侵入性写法

MobX 会在 React 组件中写上 @observer@action 等装饰器,这让仅具备 React 知识的人很难读懂任何一个组件,而在 Redux 中,connect 之前的组件完全是 React 本身的内容,你可以暂时不懂 Redux,依然能很有信心的去理解这部分的代码。

直观上看,Redux 中的 React 代码和 React 官方文档示例代码有很高的相似度,而 MobX 中的则差异很大。

可变的 State

React 中只有 State(或 Context)变化会引起界面更新,在 setState 中,是 用新的 State 替换旧的 State,所以实际上,State 被看成是只读的,不应该被直接修改。

Redux 遵从了这样的理念,在 reducer 里也是返回新的 State,并且小心的避免修改 prevState。

MobX 没有遵从,它的 State 更新是通过直接修改实现的,由于 MobX 中的 State 用的是“响应式”数据,因此任何变动会被 MobX 感知并通知到 React,也实现了数据和界面的一致。

这其实是 不可变数据(Immutable)可变数据(Mutable) 技术选型上的偏好,没有优劣之分,但是 Redux 更加 "follow React"。

响应式和函数式

MobX 和 Redux 各自鲜明的特点,体现了响应式和函数式关注点的不同:

响应式 “简单可依赖”,一个状态改变,任何引用这个状态的地方都自动更新。

函数式 “无副可预测”,相同的输入,一定能得到相同的输出。

两者并不矛盾,甚至可以并存,这也是 MobX 自称 透明的函数响应式编程(TFRP) 的原因。React 虽然取名“React”,但官方也承认,React 其实并不想那么 "reactive":

There is an internal joke in the team that React should have been called “Schedule” because React does not want to be fully “reactive”.

所以,我觉得 MobX 不适合 React,在 React/MobX 项目中,React 仅承担渲染角色,沦为 html 的 DSL,因此看起来像 "React + MobX === Vue",这是我们高傲的 React 玩家绝对无法接受的 🤣。