mobx是目前热度仅次于redux的react生态内的状态管理库。接下来做一个比较吧。
相同点
- 单向数据流;这是必然的,毕竟大部分frameworks都是差不多的,具体原因就不再冗述。
- 触发方式都是通过 action 触发全局 state 更新,然后通知所有订阅者。当然也有细微的不同,接下来看下数据流向redux
mobx
不同点
- 修改状态方式不同;从上面的图中,其实也可以很直观的感受出来,store(state)的更改方式完全不一样,redux要更繁杂一些,并且redux 是每次返回一个全新的状态,一般搭配实现对象 immutable 的库来用。mobx 每次都是修改的同一个状态对象,基于响应式代理,也就是 Object.defineProperty 代理 get、set 的处理,get 时把依赖收集起来,set 修改时通知所有的依赖做更新。和 vue2 的响应式代理很类似(vue3现在已经在使用proxy进行监听了,所以后面mobx5也使用上了proxy)。
- redux 那种方式是函数式的思路,所以状态的修改都在一个个 reducer 函数里,而 mobx 那种方式则是面向对象的代理的思路,所以很容易把 state 组织成一个个 class,而这也就决定了,为什么redux会比mobx更受欢迎,虽说mobx也提供了一些hooks使用,但终归不是正统的函数式。这也就导致了两种状态管理方式的代码组织是有区别的。redux 是在 reducer 函数里组织状态(函数式的特点)(当然这不包括toolkit或者rematch这些中间件):
const reducer = (state = 0, action) => {
switch (action.type) {
case 'INCREMENT': return state + 1;
case 'DECREMENT': return state - 1;
default: return state;
}
};
而 mobx 则是在 class 里组织状态(面向对象的特点):
import {observable, action} from 'mobx';
class Store {
@observable number = 0;
@action add = () => {
this.number++;
}
}
此外,redux 那种方式每次都要返回一个新的对象,虽然可以用 immutable 的库来减少创建新对象的开销,但是比起 mobx 直接修改原对象来说,开销还是大一点。 而且 redux 通知依赖更新的时候是全部通知下的,这也是为什么部分情况导致的重复渲染问题。而 mobx 因为收集了每个属性的依赖,可以精准的通知。 所以 mobx 的性能会比 redux 高一些。
总结
综上,mobx 和 redux 都是单向数据流,但是管理状态的思路上,一个是函数式的思想,通过 reducer 函数每次返回新的 state,一个是面向对象的思想,通过响应式对象来管理状态,这导致了状态组织方式上的不同(function/class),而且 redux 创建新的 state 的开销还有通知所有依赖的开销都比 mobx 大,性能比 mobx 差一些。 对比下来,我们会发现 mobx 似乎比 redux 优秀一些,但是代码也更繁琐写,那接下来,就是看看mobx怎么用了。
mobx的使用
mobx使用前就有一个阻碍,修饰符,在项目中配置修饰符还是比较麻烦的。如果是webpack中还好说,容易配置,但是如果项目是vite,那么就有的受了,各种方式都尝试过,整不活,虽然可以抛弃修饰符,但是这样还用mobx就没什么价值了。 因为目前正在做的脚手架是vite,所以mobx的使用滞后 @todo 参考&转载: MobX 的实现原理是?