Mobx特别容易入门级教程

14,401

Mobx 是简单、可扩展的状态管理,React 和 MobX 是一对强力组合。React 通过提供机制把应用状态转换为可渲染组件树并对其进行渲染。而 MobX 提供机制来存储和更新应用状态供 React 使用。

本篇文章只是一个简单的 Mobx 入门,他包含了本人的一些理解,如果有不对的请斧正。看完本篇文章你再看文档就不是一头雾水了。

Mobx 中文文档

我们现来看一下 Mobx 的机制。

首先从左往右看,事件触发了 Actions,Actions 作为唯一修改 State 的方式,修改了 State,State 的修改更新了计算值 Computed,计算值的改变引起了 Reactions 的改变,导致了 UI 的改变,Reactions 可以经过事件调用 Actions。

大体的机制就是这样。

开发环境

废话不多说,工先善其事必先利其器,我们先把开发环境装好。请跟着我一步一步的来。

创建项目

在此之前你需要先下载好React脚手架.

create-react-app mobxlearn --scripts-version=react-scripts-ts
// 在这里先配置Ts的开发环境,如果你不了解TS,请先看我的专栏,有TS教程

我的 TS 教程

安装依赖

npm install --save-dev babel-plugin-transform-decorators-legacy
// 修饰符的插件

npm install @babel/plugin-proposal-decorators
// 装饰器的一个插件

.babelrc

在根目录创建一个.babelrc文件.输入一下:

{
    "plugins":[
        [
          "@babel/plugin-proposal-decorators",
          {
              "legacy":true
          }
        ],
        [
          "@babel/plugin-proposal-class-properties",
          {
              "loose":true
          }
          ]
          ],
    "presets":[
        "react-app"
        ]

}

安转 Mobx 和 Mobx-react

npm install mobx mobx-react --save

开发环境到此结束。

书写 Mobx

目录结构

目录结构
目录结构

App.tsx

import { Provider } from "mobx-react"
import * as React from 'react';
import './App.css';
import Casual from "./component/Casual"
import Store from './store/store';

const store = {
  store: new Store()
}

class App extends React.Component {
  // 在这里我们要使用mobx-react里的Provider,
  // 把所有的state注入Provider中,后面的子组件都可以使用@inject("想要使用的state")注入被观察者。
  public render() {
    return (
      <Provider {...store}>
      <div>
        <Casual  />
      </div>
      </Provider>
    );
  }
}

export default App;

store.ts

import { action, computed, observable } from "mobx"

class Store {
    // 被观察者,你可以理解成Vuex中的State,也就是说,声明一些想要观察的状态,变量。
    // 被观察者可以是:JS基本数据类型、引用类型、普通对象、类实例、数组和映射
    @observable public num: number = 0;
    @observable public map: Map<string,object> = new Map();
    @observable public list: string[] = ["a","b"];
    @observable public obj: object = {name:"Mobx"};

    // 计算值是可以根据现有的状态或其它计算值衍生出的值.
    // 计算值不接受参数
    @computed
    public get retunum() {
        return `${this.num}~~~~~~~~`
    }

    @computed
    public get addNum() {
        return this.num + 10;
    }

    // 使用@action 更改被观察者
    @action.bound
    public add() {
        this.num++;
    }


}
export default Store

Casual.tsx

import {  inject, observer } from 'mobx-react';
import * as React from "react"
import Store from '../store/store';

// props要接受的值
interface IProps {
    store?: Store;
  }

@inject("store") // 将store注入
@observer   // 将Casual类转化为观察者,只要被观察者跟新,组件将会刷新
class Casual extends React.Component<IProps,{}> {

    constructor(props:IProps) {
        super(props)
    }


   public render() {
        return (
            <div>
                <h1>{this.props.store!.num}</h1>
                <h2>{this.props.store!.retunum}</h2>
                <h2>{this.props.store!.addNum}</h2>
                <button onClick={this.onClickAdd}>增加num</button>
            </div>
        )
    }

    public onClickAdd=()=>{
        this.props.store!.add()
    };


}
export default Casual