1
Using mobx to Saving Your Life...

在开发中大型应用的时候,与 React 配合使用的数据状态管理库除了有 Redux, 我们还有了新选择 -- Mobx, Mobx 是一款提供函数响应式编程的数据状态管理库, 相比于 Redux 的复杂而沉重, 它有着更简单的接口与更少的概念, 只需较少的代码, 即可把数据有效管理起来.

核心思想:

使用观察者模式监控数据的变化,当数据变化时,自动更新/渲染视图

原理:

  1. 建立数据仓库(store)与页面(view)之间的绑定关系:

    store ---> subscribe ---> view          
  2. 当数据变化时, 自动根据新数据重新渲染页面(re-render)

    subscribe(store) ---> exchange-info ---> re-render(view)
    

核心概念:

  • observable

定义:
字面意义上理解是可观察的,代表被观察的数据源,通过这个方法,将我们的数据源包裹,返回一个可以由 mobx 自动监测的数据源对象

import { observable } from 'mobx';

class DataSource {
  @observable num = 0;
}

export default DataSource;

在这里我们做了两件事情:
引入 observable 这个方法
定义 DataSource 类,通过 observable 将 DataSource 的 num 属性包装成被观测的数据源

  • observer

定义:
字面含义是 观察者, 用来监测数据源变化,当使用 observer 订阅数据源后,会根据数据源的变化来自动渲染新视图

import React from 'react';
import { observer } from 'mobx-react';
import DataSource from './DataSource'; // 1.引入数据源的类
const dataStore = new DataSource();    // 2.实例化数据仓库 (data store)

@observer                              // 3.使用装饰器包装后面的App类,使其可以使用data store里的数据
export default class App extends React.Component {
    render() {
      return (
        <div>{ dataStore.num }</div>     // 4.通过 @observer 包裹后的组件监测 dataStore 中的 num 数据
      );
    }
}

在这里通过 @observer 把 App 组件改造成了观察者,并观测实例化的数据对象后,我们就轻松很多了,因为 mobx 会在 dataStore 中的 num 变化时 自动重新渲染视图,
那如何做到手动改动数据,或是做异步请求来改变数据呢?

  • action

定义: 使用 action (动作) 来定义数据仓库中改变数据源的方法
那我们就把 observable 中的例子改成这个样子:

import { observable, action } from 'mobx';
class DataSource {
  @observable num = 0;
  @action add = () => {                // 使用 @action 装饰 add 这个方法, 当我们调用 add 的时候
   this.num++;                        // DataSource 中的 num 值就会自增1了
 }
}
export default DataSource;

然后, 把 observer 中的例子改成这个样子:

import React from 'react';
import { observer } from 'mobx-react';
import DataSource from './DataSource';  // 1.引入数据源的类
const dataStore = new DataSource();     // 2.实例化数据源 (data store)

@observer                               // 3.使用装饰器包装 App 组件, 使其可以使用 dataStore 中的数据
export default class App extends React.Component {
    render() {
        return (
            <div>{ dataStore.num }</div>                 // 4. 绑定 num 数据
            <button onClick={ dataStore.add }></button>  // 5. 绑定 add 方法
        );  
    }
}

在视图中绑定这个方法后, 当我们点击的时, 就能触发 dataStore 的数据变化了
但是业务中经常用的 异步请求呢,怎么写?

import axios from 'axios';                // 1. 引入 http 库

@action requestData = async() => {        // 2. 使用 @action 包装异步函数
    const data = await axios.request({    
        method: 'GET',
        url: 'https://www.baidu.com'
    });
    this.num = data;
}

// view层
加一个button
<button onClick={ dataStore.requestData }></button>  // 3. 添加 requestData 方法

加上 requestData 方法后,点击按钮,神奇的事情出现了,视图中的数字自动变化成了我们请求回来的结果!!

What's the diffenrece?
相比于 Redux 从 View -> Mutation -> Action -> Reducer -> Store 的链路, Mobx 只需要从 @observer 到 @observable,
在节省大量开发 Mutation/Action/Reducer 的代码的同时, 也减少了出错的机率与调试的成本.
即然 redux 能做的 mobx 也能做,同时还能节省开发成本,何乐而不为呢,快来体验一下化繁为简的快乐吧.

Mobx, 化繁为简的艺术, 愉快的初次体验


跨越银河Galaxy
17 声望0 粉丝