observable 的属性值在其变化的时候 mobx 会自动追踪并作出响应。
在一个数据管理框架库中,其最重要的就是它的数据管理模式了,也就是其数据流。对于 MobX 来说,它的数据流简明清晰,并且也是单向数据流
它由几个部分组成:Actions、State、Computed Values、Reactionsa
在整个数据流中,通过事件驱动(UI 事件、网络请求…)触发 Actions,在 Actions 中修改了 State 中的值,这里的 State 既应用中的 store 树(存储数据),然后根据新的 State 中的数据计算出所需要的计算属性(computed
values)值,最后响应(react)到 UI 视图层。
@observable 修饰器转可观测一个数据,@observable 接受任何类型的 js 值(原始类型、引用、纯对象、类实例、数组和、maps),如果变化的值处在autorun中,那么autorun就会自动执行。
@observable classProperty = value
当应用状态更新时,所有依赖于这些应用状态的监听者(包括UI、服务端数据同步函数等),都应该自动得到细粒度地更新。
当然在这里可以加一些调节器来做一些配置:
const number = observable(10);
const plus = computed(() => number.get() > 0);
autorun(() => {
console.log(plus.get());
});
number.set(-19);
number.set(-1);
number.set(1);
依次输出了true,false,true。
第一个true是number初始化值的时候,10>0为true没有问题。
第二个false将number改变为-19,输出false,也没有问题。
但是当-19改变为-1的时候,虽然number变了,但是number的改变实际上并没有改变plus的值,所以没有其它地方收到通知,因此也就并没有输出任何值。
直到number重新变为1时才输出true。
顺便一提,computed属性和React Native中的ListView搭配使用很愉快。
修改被观测变量的行为放在action中。
import {
observable, action} from 'mobx';
class Store {
@observable number = 0;
@action add = () => {
this.number++;
}
}
const newStore = new Store();
newStore.add();
Mobx的非严格模式
import {
observable, action, useStrict} from 'mobx';
useStrict(true);
如果你使用async function来处理业务,那么我们可以使用runInAction这个API来解决之前的问题。
import {
observable, action, useStrict, runInAction} from 'mobx';
useStrict(true);
class Store {
@observable name = '';
@action load = async () => {
const data = await getData();
runInAction(() => {
this.name = data.name;
});
}
}
安装
npm i mobx mobx-react
## 装饰器语法babel7
cnpm install --save-dev @babel/plugin-proposal-decorators
.babelrc文件配置
{
"presets": [
"react-app"
],
"plugins": [
[
"@babel/plugin-proposal-decorators",
{
"legacy": true
}
],
]
}
react中的入口文件index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import {
Provider } from 'mobx-react'
import Store from './store/index'
ReactDOM.render(<Provider {
...Store}><App /></Provider>, document.getElementById('root'));
//Provider为根
//如果使用Provider配合inject,把多个store,配到根上,子组件通过inject自动注入。
react中的页面文件 App.js
import React, {
Component } from 'react'
import {
inject, observer } from 'mobx-react'
//注入文件
@inject('homeStore')
@observer
class ComponentName extends Component {
render() {
return (
<div>
<h3>{
this.props.homeStore.num}</h3>
<button onClick={
() => {
this.props.homeStore.add() }}>加一</button>
</div>
)
}
componentDidMount() {
//调用日志
console.log(this.props.homeStore.total)
}
}
export default ComponentName;
store文件下index.js
import Homestore from './home/index'
const homeStore = new Homestore()
export default{
homeStore
}
store文件下hoem/index.js
import {
observable, action, autorun, computed } from 'mobx'
class Homestore {
//初始化状态
@observable num = 0
//
constructor() {
this.num = 0;
}
//计算属性
@computed get total() {
return this.num
}
set tol(value) {
this.num = 10
}
//触发行为
@action add() {
this.num += 1;
}
}
//可以看成日志,状态变化,日志就会触发
autorun(() => {
console.log(Homestore.prototype.num);
});
export default Homestore;