Mobx状态管理
1.原理
React和MobX是一对强力组合。React的render机制,是通过管理state的状态变化来渲染组件,而Mobx则提供了一种响应式的存储、更新状态的方法。
使用MobX将应用变成响应式可归纳为三部曲:
- 定义状态并使其可观察
- 创建视图以响应状态的变化
- 更改状态
在介绍这三个步骤之前,我们先通过一个demo了解下MobX的核心API(observable、observer、action)。
2.MobX核心API(适用mobx 4.X/ mobx 5.X)
observable: 使用ES7的装饰器(@observable)将类属性等进行标记,使其变成可观察状态。三部曲中的第一曲,就是通过Observable实现的。
observer: 通过 observer(ReactComponent) 定义组件,使其变成观察者,监听observable的变化。
action: observable只能在 action 中修改状态。
简化图如下:
3.使用步骤
1. 安装
安装mobx:npm install mobx --save
React安装React绑定库:npm install mobx-react --save
2. 新建Store文件
在src目录下新建stores文件夹,observable的相关文件存储在此,建议一个页面对应一个store管理文件,若页面逻辑接口过多,建议细分为逻辑处理和接口对接2个文件管理。
3. 定义observable并使其可观察
引入observable依赖,定义可观察数据。
import { observable } from "mobx";
class Todo {
@observable test = "Mobx状态管理";
}
4. 创建视图以响应状态的变化
首先引入observable依赖和需要观察的observable文件。
import { observer } from "mobx-react";
import Todo from "@/stores/Todo";
然后用observer包裹React组件的高级组件,使其可以响应observable的状态变化。
@observer
export default class Index extends Component {
render(){
return(
<div>
<p>{Todo.test}</p>
</div>
)
}
}
5. action更改状态
在stores文件中引入action依赖,定义action方法改变obserbale的状态。
import { observable, action } from "mobx";
class Todo {
@observable test = "Mobx状态管理";
@action change =()=>{
this.test = "Mobx是React的好帮手";
}
}
视图层调用action方法,以改变observable的值,使其重新渲染。
import { observer } from "mobx-react";
import Todo from "@/stores/Todo";
@observer
export default class Index extends Component {
componentDidMount(){
setTimeout(() => {
Todo.change(); }, 3000);
}
render(){
return(
<div>
<p>{Todo.test}</p>
</div>
)
}
}
上述代码执行后,页面初始化显示文字"Mobx状态管理",在3秒后,执行change()方法,改变test的值,而视图层监听到test的改变后,重新渲染,页面文字变成"Mobx是React的好帮手"。
4.MobX6.0版本更新
mobx近期更新了6.0版本,与4.X/5.X版本在store的写法有所区别。先看下6.0版本的写法:
import { makeAutoObservable} from "mobx";
class Todo {
constructor() {
makeAutoObservable(this)
}
test = "Mobx状态管理";
change =()=>{
this.test = "Mobx是React的好帮手";
};
}
6.0版本不需要通过observable和action等修饰器,直接在构造函数中使用makeAutoObservable来实现observable和action修饰器功能,使代码更加简洁。
5.参考文档
官方中文文档:https://cn.mobx.js.org/
mobx简介以及和redux的对比:https://zhuanlan.zhihu.com/p/27976892