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;
    });
  }