十分钟入门状态管理工具Mobx

什么是Mobx

一个简单,可拓展的状态管理工具

安装

npm install mobx --save

核心概念

flow.png

State(状态)

状态是驱动应用的数据,状态的改变会影响视图。react

import {observable, autorun} from 'mobx';
var todoStore = observable({
    /* 一些观察的状态 */
    todos: []
});

Derivations(衍生)

任何源自状态而且不会再有任何进一步的相互做用的东西就是衍生。git

import {observable, autorun} from 'mobx';
var todoStore = observable({
    /* 一些观察的状态 */
    todos: [],
    /* 衍生值 */
    get completedCount() {
        return this.todos.filter(todo => todo.completed).length;
    }
});
注意:衍生值必须是纯函数

Actions(动做)

动做是一段能够改变状态的代码。用户事件、后端数据推送、预约事件、等等。github

使用原则

MobX 支持单向数据流,也就是动做改变状态,而状态的改变会更新全部受影响的视图。
ajax

一、当状态改变时,全部衍生都会进行原子级的自动更新。
二、全部衍生默认都是同步更新。这意味着例如动做能够在改变状态以后直接能够安全地检查计算值。
三、计算值 是延迟更新的。任何不在使用状态的计算值将不会更新,直到须要它进行反作用(I / O)操做时。 若是视图再也不使用,那么它会自动被垃圾回收。
四、全部的计算值都应该是纯净的。它们不该该用来改变状态。

举个例子:npm

import { observable,computed, action } from 'mobx';
class ObservableTodoStore {
    //定义可响应状态
    @observable todos = [];
    @observable pendingRequests = 0;
    
    //衍生值
    @computed get completedTodosCount() {
        return this.todos.filter(
            todo => todo.completed === true
        ).length;
    }

    @computed get report() {
        if (this.todos.length === 0)
            return "<none>";
        return `Next todo: "${this.todos[0].task}". ` +
            `Progress: ${this.completedTodosCount}/${this.todos.length}`;
    }
    
    //动做
    @ction
    addTodo(task) {
        this.todos.push({
            task: task,
            completed: false,
            assignee: null
        });
    }
}

const observableTodoStore = new ObservableTodoStore();

使用装饰器@

装饰器会看起来更友好一些,使用babel-preset-mobxjson

npm install --save-dev babel-preset-mobx

安装后在package.json中配置后端

52123F5E-50A3-441f-B1FB-FF49C2F7D948.png

解决异步更新state

class Store {
    //定义状态
    @observable listData = []
    @observable state = "pending";
    
    //异步行为修改状态,好比向服务器请求数据
    @action
    async fetchProjects() {
        this.state = "pending"
        try {
            const filteredProjects = await ajaxData();
            // await 以后,再次修改状态须要动做:
            runInAction(() => {
                this.state = "done"
                this.listData = filteredProjects
            })
        } catch (error) {
            runInAction(() => {
                this.state = "error"
            })
        }
    }
}

runInAction是一个工具函数。只在动做中运行回调函数中状态修改的部分,而不是为整个回调建立一个动做。 这种模式的优点是它鼓励你不要处处写 action,而是在整个过程结束时尽量多地对全部状态进行修改。安全

一个完整的例子:

整个应用状态管理入口:服务器

import React from 'react';
import ReactDOM from 'react-dom';
import { ConfigProvider } from 'antd';
import App from './App';
import zhCN from 'antd/es/locale/zh_CN';
import { Provider } from 'mobx-react';
import stores from '@/stores'

ReactDOM.render(<ConfigProvider locale={zhCN}>
    <Provider {...stores}><App /></Provider>
</ConfigProvider>, document.getElementById('root'));

store统一管理:babel

import permissionStore from './permission';
const stores={
    permissionStore
}
export default stores;

定义单文件store

import { observable, action, runInAction } from 'mobx';
import $http from '@/utils/http';
class PermissionStore {
    @observable menus = [];
    @action
    async fetchMenus() {
        try {
            let menus = await this.handleFetchMenus();
            runInAction(() => {
                this.menus = menus;
            })
        } catch (error) {
            
        }
    }
    handleFetchMenus() {
        return $http("/permission/menuList").then(resp => {
            if (resp && resp.items && resp.items.length) {
                return resp.items;
            }
        });
    }
}
export default new PermissionStore();

组件绑定

import React from 'react';
import { observer, inject } from 'mobx-react'

@inject('permissionStore');//引入对应的store
@observer
class SideMenu extends React.Component {
    constructor(props) {
        super(props);
    }
    componentDidMount() {
        const { permissionStore } = this.props;//从props中获取store
        permissionStore.fetchMenus();//store中的异步action
    }
    //生成菜单栏
    renderMemu = () => {
        let { menus } = this.props.permissionStore;//获取状态,此时数据是异步从服务器获取后更新的数据状态
        return (
           ...
        )
    }
    render() {
        return (
            {this.renderMemu()}
        )
    }
}
export default SideMenu

mobx涉及的核心概念就三个,State(状态),Derivations(衍生值)和Actions(动做),使用起来很是简单和清晰,能够快速上手,是一个不错的状态管理工具,github star有21K。

相关文章
相关标签/搜索