状态管理器 - MobX

MobX 是一个经过战火洗礼的库,它通过透明的函数响应式编程使得状态管理变得简单和可扩展。

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

一、搭建环境依赖

安装mobx

npm install mobx mobx-react --save

或在浏览器上使用cdn

https://unpkg.com/mobx/lib/mobx.umd.js
https://cdnjs.com/libraries/mobx

 

二、启用装饰器语法:

大多数人使用mobx都会选择使用装饰器语法(你也可以选择不使用装饰器,则无需启用装饰器)。

使用装饰器语法的优势:

  • 样板文件最小化,声明式代码。
  • 易于使用和阅读。大多数 MobX 用户都在使用。

装饰器语法需要在es7或者在typescript中使用,如果你的环境不支持装饰器,需要手动开启开启装饰器语法。

1、安装装饰器所需依赖

npm install @babel/plugin-proposal-decorators --save-dev  // 安装在本地即可

2、释放配置文件

npm run eject

如果出错,执行以下命令,再次执行释放配置文件:

git add .
git commit -am "msg"

3、修改package.json中的babel配置

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

到此已经配置完成。


三、基本使用

1、定义状态

使用装饰器:

import {action, observable, computed} from 'mobx';
class AppState {
    @observable count = 0;
    @computed get countText(){    // 计算值,当运算值中的其中一个值发生变化时都会重新计算
        return '数值:' + this.count
    }
    @action.bound addCount(){    // 定义一个action,该action每次为count+1。 添加bound修饰绑定对象,可保证this指向永远正确的
        this.count++
    }
}
export default new AppState();    // 实例化当前类并导出

不使用装饰器:

import {action, observable, computed, decorate} from 'mobx';  // 注意导入decorate 
class AppState {
    count = 0;
    get countText(){
        return '数值:' + this.count
    }
    addCount(){    // 定义一个action,该action每次为count+1
        this.count++
    }
}
decorate(SppState,{
    count: observable,
    countText: computed,
    addCount: action.bound   // 添加bound修饰绑定对象,可保证this指向永远正确的
})
export default new AppState();    // 实例化当前类并导出

​

需要使用 decorate 工具,decorate 接受两个参数,第一个是目标对象,第二个参数为装饰器属性参数

 

2、创建视图

使用装饰器

import {observer} from 'mobx-react'
@observer
class Page extends React.Component {
    render() {
        return (
            <div>
                <button onClick={this.props.appState.addCount}>添加</button>  // 如果定义action时没有使用bound修饰绑定对象,则需要使用匿名函数执行调用
                当前数量:{this.props.appState.count}
            </div>
        )
    }
}
export default Page;

不使用装饰器

import {observer} from 'mobx-react'
function Page(props) {
    return (
        <div>
            <button onClick={this.props.appState.addCount}>添加</button>  // 如果定义action时没有使用bound修饰绑定对象,则需要使用匿名函数执行调用
            当前数量:{props.appState.count}
        </div>
    )
}
export default observer(Page);  // 使其可观察并导出

3、绑定appState到视图组件上

import appState from './store/index' // 路径根据实际情况而定
import Timer from './pages/Timer'  // 导入视图组件
function App() {
	return (
		<div>
			<Timer appState={appState}></Timer>    // 通过props传递
		</div>
	);
}

到此一个简单的示例已经完成了!

 

三、使用 Provider、inject 工具

接着上面示例,我们给视图组件传递store时,需在组件上传递props,目前看似无所谓,但是,如果组件多了,我们需要给给个组件都写上同样的props,比较麻烦,不易维护,不美观。我们可以通过引入Provider、inject解决此类问题。

1、Provider

Provider是一个组件,一般包裹在左右视图组件的最外层,以实现所有组件的全局context,在所需组件里可以通过inject获取store。

import {Provider} from 'mobx-react';
import appState from 'store/index';  // 引入store
function App() {
	return (
		<Provider store={appState}>    // 挂载全局store
			<Timer></Timer>
		</Provider>
	);
}

mobx是可以拆分为多个store的,那么多个store如何挂载全局呢?

​
import {Provider} from 'mobx-react';
import {appState,appState2,appState3} as stores from 'store/index';  // 引入多个store
function App() {
	return (
		<Provider {...stores}>    // 挂载全局store
			<Timer></Timer>
		</Provider>
	);
}

​

2、inject

inject用于注入store, 在Provider包裹下的视图组件可以通过@inject('store')的方式注入。

@inject('store')  // 按照挂载时的名称进行注入
class Page extends React.Component {...}

还可以注入多个store

@inject('store','store2','store3')  // 注入多个store
class Page extends React.Component {...}

注入后,组件内可以通过 this.props.store的方式获得状态。

 

 

MobX中文文档:https://cn.mobx.js.org/

注:个人笔记,不作标准答案,仅供参考。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章