mobX简介
在 react 项目中,可以使用 context、redux 来做状态管理,同样也可以使用 mobx 来做状态管理。从操作方面来讲,mobx 比 redux 的操作更简单。
mobx 的核心概念有 observable
、computed
、reactions
和 actions
,掌握这几个概念,就可以在项目中游刃有余地使用 mobx了。
本篇文章主要讲解 mobx 中的几个核心概念,如果想了解在react项目中如何使用mobx,可以查看另一篇文章,在React项目中使用mobx实现简单的todolist功能
1. 安装
在终端中执行yarn add mobx -S
,安装 mobx 到生产环境中。
2. observable
使用observable
来定义一个可观察的状态
,类似于redux 中 store 里的数据。可以采用声明式定义,也可以使用装饰器的写法。
要声明对象
或者数组
类型的变量可以直接在 observable()
中传入对应的数据,如果是声明 js 基础类型的变量,需要使用 observable.box()
。
import {observable} from 'mobx';
//map类型:
const map=observable.map
map.set('a',100)
map.get('a')
//对象类型:
const obj=observable({a:3,b:4})
//数组类型:
const arr=observable(['a','b','c'])
//定义js基础类型,要使用observable.box():
const num=observable.box(10) //number类型
num.set(2) //使用set()修改
console.log(num.get()) //2 使用get()读取
const str=observable.box('hello')//string类型
str.set('hahha') //使用set()修改
console.log(str.get()) //hahha 使用get()读取
装饰器写法,如果使用 @observable
装饰器,要确保在你的编译器(babel 或者 typescript)中装饰器是启用的。
//装饰器的写法:
class Store{
@observable arr=[];
@observable str='hahaha';
@observable num=3;
@observable bool=true;
}
3 computed
- 使用
computed
可以根据现有的状态或其它计算值衍生出新的值,当数据有变化时,会自动计算出新的值。 computed()
是一个函数,当调用该函数的时候会执行。- 同样也可以使用装饰器
@computed
的语法来写。
import {computed} from 'mobx'
class Store {
@observable str = "hello"
@observable num = 10
//只要str 和 num有变化 ,就可以返回新的result
const result=computed(()=>{
return sotre.str+store.num;
})
//装饰器的写法
@computed
get result() {
return this.str + this.num;
}
}
4. reactions
computed
计算值
是自动响应状态变化的值。 reactions
反应
是自动响应状态变化的副作用。它用来监听observable 的变化,执行对应的操作。
4.1 autorun
autorun
的特点是它默认会自动执行一次
,只要autorun里相关的任何数据有变化 ,autorun都会执行。
import {autorun} from 'mobx'
class Store {
@observable str = "hello"
@observable num = 10;
}
const store = new Store()
autorun(() => {
console.log(store.str+store.num); //hello10
})
注意:不要把 computed 和 autorun 搞混。它们都是响应式调用的表达式,但是,如果你想响应式的产生
一个可以被其它 observer 使用的值
,请使用 @computed
,如果你不想产生一个新值,而想要达到一个效果,请使用 autorun。
4.2 when
when
接收两个函数参数
,第一个函数返回一个boolean
值,只有当第一个函数返回值为ture
时,才会执行第二个函数。
import {when} from 'mobx'
class Store {
@observable bool = true
@observable num = 10
}
const store = new Store()
when(()=>store.bool,()=>{
console.log(store.num) //10
})
4.3 reaction
- reaction 默认不会自动执行。
- 它可以说是
autorun
的变种
,接收两个函数作为参数。 - 第一个函数必须有返回值,只有当第一个函数
返回值有变化后
,才会执行
第二个函数。 - 第一个函数每次返回新的值,都会执行第二个函数,也就是说修改
几次
数据,就会执行几次
第二个函数。 - 第二个函数中的的第一个参数为第一个函数返回的数据。
import {reaction} from 'mobx'
class Store {
@observable str = "hello"
@observable num = 10
}
const store = new Store()
reaction(()=>{
return [store.str,store.num]
},(data)=>{ //data为第一个参数中返回的数据
console.log(data) //hello 10
})
5. action
- 使用
action
对observable
进行修改,直接在修改数据的方法前面加@action
装饰器就可以。 runInAction()
是进行异步操作时,它其实是action() 的语法糖。@action.bound
解决this指向的问题,用来自动地将动作绑定到目标对象。
注意: action.bound 不要和箭头函数一起使用;箭头函数已经是绑定过的并且不能重新绑定。
import {action} from 'mobx'
class Store {
@observable str = "hello"
@observable num = 10
@action //对数据进行修改
bar() {
this.str = "hello world"
this.num = 100
}
@action.bound //解决this指向的问题
increment() {
this.num++ // 'this' 永远都是正确的
}
//异步操作写在runInAction()中
runInAction(()=>{
this.num = 100
})
更多的API介绍可以查看mobX官网:https://cn.mobx.js.org