mobx api 使用装饰器语法 mobx数据转化为js数据
安装
yarn add mobx mobx-react
yarn add babel-preset-mobx --dev
"presets": ["mobx"]
添加 /src/store/index.js
import {
observable,
action,
computed
} from 'mobx'
class Store {
@observable state = {
title: 'Header..'
}
@computed get get_header() {
return this.state.title + 'Ajanuw';
}
@action.bound set_title() {
if (Math.random() > 0.5) {
this.state.title += '.'
} else {
let title = this.state.title
if (title[title.length - 1] !== '.') return;
this.state.title = title.substring(title.length - 1, 0);
}
}
}
export default new Store();
/src/App.js
import React, { Component } from 'react';
import './App.css';
import { observer } from 'mobx-react'
import store from './store/index';
const Play = observer( prop =>{
return (
<div>
<div>{ store.get_header}</div>
<button onClick={ store.set_title }>change</button>
</div>
);
});
@observer
class App extends Component {
render() {
return (
<div className="App">
<Play />
</div>
);
}
}
export default App;
使用rxjs
@action.bound change(){
of(toJS(this.state.msg))
.pipe(
map(v => v += '..')
).subscribe(v => this.state.msg = v);
}
节流
<Button color='secondary' onClick={store.getJson('ajanuw')}>Get Json</Button>
@action.bound getJson = name => throttle( e => {
l(name)
}, 2000);
最佳实践 RootStore
// 插入到组件树
import { Provider, inject } from "mobx-react";
import RootStore from "./store/root.store";
<Provider {...new RootStore()}>
<App />
</Provider>
---
// 创建 RootStore
import IndexStore from "./index.store";
import WelcomeStore from "./welcome.store";
class RootStore {
constructor() {
this.indexStore = new IndexStore(this);
this.welcomeStore = new WelcomeStore(this);
}
}
export default RootStore;
---
// 单个 store
import { observable, action, computed } from "mobx";
const l = console.log;
class IndexStore {
constructor(rootStore) {
this.rootStore = rootStore;
}
@observable
name = "indexStore";
@action.bound
test() {
// 使用另一个store的数据
l(this.rootStore.welcomeStore.name);
}
}
export default IndexStore;
---
// 使用
@inject(({ indexStore }) => ({ indexStore }))
componentWillMount() {
this.props.indexStore.test()
}
关于 action
箭头函数不需要设置bound,传递参数的函数把action绑定在第二个函数上
@action.bound
asd() {
this.a = 1;
this.s = 2;
}
@action
asd = () => {
this.a = 1;
this.s = 2;
};
asd = k =>
action(() => {
this.a = 1;
this.s = 2;
});
在组件中传递 mobx的数据
MobX 追踪属性访问,而不是值
尽量使用上面的实例
const Title = observer(({ children }) => <h2>{children.title}</h2>);
<Title>{data}</Title>
const Title = observer(({ children }) => <h2>{children}</h2>);
<Title>{data.title}</Title>
异步方法最好使用 runInAction
@action.bound
async getList() {
let r = await getData();
runInAction(() => {
this.list = r;
});
}