mobx入门

是类似于vuex,redux,flux的状态管理工具

使用方式 需要下载npm install mobx和mobx-react

//引入需要的组件

import {observable, autorun, action, runInAction} from 'mobx';

observable

接受的值可以是JS基本数据类型、引用类型、普通对象、类实例、数组和映射

顾名思义就是接受的值被观察了,监测到变化后会产一系列事件,简单的用法一般用来创建项目中的store

//用法一
const map = observable.map({ key: "value"});
map.set("key", "new value"); //监测到变化了

const list = observable([1, 2, 4]);
list[2] = 3;//监测到变化了

const person = observable({
    firstName: "Clive Staples",
    lastName: "Lewis"
});
person.firstName = "C.S."; //监测到变化了

const temperature = observable(20);
temperature.set(25); //监测到变化了

// 用法二

@observable public counter: number;


import { observable, computed } from "mobx";

class OrderLine {
    @observable price = 0;
    @observable amount = 1;

    @computed get total() {
        return this.price * this.amount;
    }
}


///////////////
import React, {Component} from 'react';
import { render } from 'react-dom';
import {observable} from 'mobx';
import {observer} from 'mobx-react';

// 最简单的 mobx 就是一个观察者模式

class Store {
  // 被观察者
  @observable todos = [{
    title: "完成 Mobx 翻译",
    done: false,
  }];
}

// 观察者
@observer
class TodoBox extends Component  {
  render() {
    return (
      <ul>
        {this.props.store.todos.map(todo => <li>{todo.title}</li>)}
      </ul>
    )
  }
}


const store = new Store();

render(
  <TodoBox store={store} />,
  document.getElementById('root')
);


computed 计算属性

根据依赖的值进行重新计算

import { observable, computed } from "mobx";

class OrderLine {
    @observable price = 0;
    @observable amount = 1;

    @computed get total() {
        return this.price * this.amount;
    }
}

Autorun

类似于computed 如果你有一个函数应该自动运行,但不会产生一个新的值,请使用autorun。 其余情况都应该使用 computed

var numbers = observable([1,2,3]);
var sum = computed(() => numbers.reduce((a, b) => a + b, 0));

var disposer = autorun(() => console.log(sum.get()));
// 输出 '6'
numbers.push(4);
// 输出 '10'

disposer();// 这个位置很重要
numbers.push(5);
// 不会再输出任何值。`sum` 不会再重新计算。

observer

observer 函数/装饰器可以用来将 React 组件转变成响应式组件。简单的说就是将组件与数据绑定,数据变化,组件自动更新

// 使用方法
import {observer} from "mobx-react";

var timerData = observable({
    secondsPassed: 0
});

setInterval(() => {
    timerData.secondsPassed++;
}, 1000);

@observer class Timer extends React.Component {
    render() {
        return (<span>Seconds passed: { this.props.timerData.secondsPassed } </span> )
    }
};

ReactDOM.render(<Timer timerData={timerData} />, document.body);

action

一步操作或者其他其他函数的内容改变底层store时需要使用 action

@action  createRandomContact() {
    this.pendingRequestCount++;
    superagent
        .get('https://randomuser.me/api/')
        .set('Accept', 'application/json')
        .end(action("createRandomContact-callback", (error, results) => {
            // ^ Note: asynchronous callbacks are separate actions!
            if (error)
                console.error(error);
            else {
                const data = JSON.parse(results.text).results[0];
                const contact = new Contact(this, data.dob, data.name, data.login.username, data.picture)
                contact.addTag('random-user');
                this.contacts.push(contact);
                this.pendingRequestCount--;
            }
        }));
}


set get

var Person = function(firstName, lastName) {
    // 在一个新实例上初始化 observable 属性
    extendObservable(this, {
        firstName: firstName,
        lastName: lastName,
        get fullName() {
            return this.firstName + " " + this.lastName
        },
        set fullName(newValue) {
            var parts = newValue.split(" ")
            this.firstName = parts[0]
            this.lastName = parts[1]
        }
    });
}
Copy






使用 inject 将组件连接到提供的 stores

注意: 从 mobx-react 4开始,注入 stores 的语法发生了变化,应该一直使用 inject(stores)(component) 或 @inject(stores) class Component…。 直接传递 store 名称给 observer 的方式已废弃。

简单的说就是把store中的数据变成组件中的props中可以取到的值

 const colors = observable({
   foreground: '#000',
   background: '#fff'
});

const App = () =>
  <Provider colors={colors}>
     <app stuff... />
  </Provider>;


//用法1

const Button = inject("colors")(observer(({ colors, label, onClick }) =>
  <button style=
    onClick={onClick}
  >{label}<button>
));

// 稍后..
colors.foreground = 'blue';
// 所有button都会更新
 
 
 //用法2  推荐
 @inject("colors") @observer
class Button extends React.Component {
  render() {
    return (
      <button style=>
        {this.props.children}
      </button>
    );
  }
}

 
 这样就可以在props里直接读取到store的数据

注意点

这时候需要

import { toJS } from 'mobx';
.......
 toJS(this.props.data)

然后就可以继续使用了