在react中使用管理状态工具mobx 入门案例

redux和mobx都是react比较热门的状态管理工具, 关于两者的差异, 在文章末尾会有介绍。

一、工作流图

先引用一张图解释一下mobx的工作流程:
在react中使用管理状态工具mobx 入门案例

在mobx中, 数据是通过加 @observable 作为可监测的被观察者, 在view层中, 你可以通过添加@observer 将view作为观察者,对数据进行监测, 如果要触发改变数据,则使用@action, 事实上,你可以直接在view层改变数据, 但这种方式不便监控数据,因此不推荐直接改变数据。 而@computed可以用来计算数据, 也可以是计算多个数据之后返回新的数据, 如果其中数据改变, @computed也会触发改变。下面具体说说mobx的一些基本概念。

二、概念介绍

mobx官网推送门

1:被观察observable

被observable修饰的state数据将会暴露给整个app,各观察者组件都可以根据state值的变化作出响应。

用法:
observable(value)
@observable classProperty = value

Observable 值可以是JS基本数据类型、引用类型、普通对象、类实例、数组和映射。
需要注意的是,(1)只有对象上已经存在的属性,才能被observable所观测到。
若是当时不存在,后续添加的属性值,则需要使用extendObservable来进行添加。
(2)如果是由构造函数创建的对象,那么必须要再它的构造函数中使用observable或extendObservable来观测对象。

function MyObject(name) {
  extendObservable(this, {
    name,
  });
}

var obj = new MyObject("aaa");

(3)Observable Arrays并不是一个真正的数组, 如果要转换可以 用slice创建一个浅拷贝, Array.isArray(observable([]).slice())会返回true。

2:观察者observer

被observer修饰的组件,将会根据组件内使用到的被observable修饰的state的变化而自动重新渲染(原理:用autorun包裹了render函数,state变化触发autorun从而自动渲染)

3: action
任何应用都有动作。动作是任何用来修改状态的东西。
使用MobX你可以在代码中显式地标记出动作所在的位置。 官网建议在任何更改 observable 或者有副作用的函数上使用动作。

4: 衍生值computed
创建计算值,expression 不应该有任何副作用而只是返回一个值。 如果任何 expression 中使用的 observable 发生改变,它都会自动地重新计算,但前提是计算值被某些 reaction 使用了。

get和set可以用来控制computed的行为:
get:基于state值,通过一些计算得到的新值并返回给调用者。
set:get的相反运算,参数为一个值,由该值进行get函数中的反运算,得到对应的state值并赋予state。

5: Reactions(反应) & Derivations(衍生)

基于state的变化而触发的一系列行为(注意:这些行为不改变state值、不产生新的数据),通常为日志记录、请求发送、UI渲染等。

6: autorun
用法:autorun(() => { sideEffect }, options) 。
autorun 负责运行所提供的 sideEffect 并追踪在sideEffect运行期间访问过的 observable 的状态。
将来如果有其中一个已使用的 observable 发生变化,同样的sideEffect会再运行一遍。 autorun 返回一个清理函数用来取消副作用。

扩展

掌握了上面的基本概念,Mobx的使用流程就清晰了:

新建一个mobx目录,在其中新建一个appStore.js文件,专门用于管理整个app的state。appStore中定义一个Component,在组件中:

1:定义需要被全局观察的state,用@observable修饰

2:定义改变state的行为函数,用@action修饰

3:定义基于某state,通过计算产生新值的get函数,用@computed修饰

4:定义基于所传参数,通过计算得到state值的set函数,用@computed修饰

5:定义基于state变化,自动触发的行为函数,用@autorun修饰

6:在文件末尾,新建一个该组件的实例,并export

然后,在其他组件文件中,就可以import 这个组件实例,直接使用 组件实例.XXX 访问数据、方法了。

注意:其他组件是观察者组件,用@observer修饰。

三、搭建mobx框架
1. 目录结构
在react中使用管理状态工具mobx 入门案例
2. 在store文件夹中有一个根目录,子store需要在这个根store中注册,这些store是用来存放被观察的属性以及触发操作的actions, 这有点类似于redux的model层;
根目录store文件:
在react中使用管理状态工具mobx 入门案例
子store文件:
在react中使用管理状态工具mobx 入门案例
3. 在pages中存放的是各个页面的view元素,
在react中使用管理状态工具mobx 入门案例
4. 在components中存放的是各个组件文件, 这里将store文件放在了各个组件下面,其实你也可以将store存放在store文件夹下。
在react中使用管理状态工具mobx 入门案例
我们可以看到,这页面中使用了@inject来注册store,这是mobx的核心之处, 不同于redux的单一数据流, mobx中,你可以同时在各个地方使用同一份state, 也可以在一个页面中使用多个store文件。

  1. 在日常使用中我们通常会再建一个services文件夹, 用来存放接口方法。

完整案例请看这里: https://stackblitz.com/edit/react-sbgkk6?file=index.js

文末彩蛋:
redux VS mobx (知乎)
Redux、MobX 数据流的总结(github)
react-mobx-cart 简单示例(github)
Mobx使用详解(简书)
摆脱redux繁琐操作,搭建mobx框架(掘金)