十分鐘入門狀態管理工具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。

相關文章
相關標籤/搜索