Ten minutes to get started status management tool Mobx

What is Mobx

A simple and expandable state management tool

install

npm install mobx --save

Core concept

State

State is the data that drives the application, and the change of state will affect the view.

import {observable, autorun} from 'mobx';
var todoStore = observable({
    /* Some observed states */
    todos: []
});

Derivations (derivative)

Anything that comes from a state and no further interaction is a derivation.

import {observable, autorun} from 'mobx';
var todoStore = observable({
    /* Some observed states */
    todos: [],
    /* Derived value */
    get completedCount() {
        return this.todos.filter(todo => todo.completed).length;
    }
});

Note: derived values must be pure functions

Actions

An action is a piece of code that changes state. User events, back-end data push, scheduled events, and so on.

Usage principle

MobX supports one-way data flow, that is, action changes state, which updates all affected views.

1. When the state changes, all derivatives will be automatically updated at the atomic level.
2. All derivatives are synchronized by default. This means that an action, for example, can safely check the calculated value directly after changing the state.
3. The calculated value is delayed to update. Any calculated value that is not in use will not be updated until it is required for side effect (I / O) operations If the view is no longer in use, it is automatically garbage collected.
4. All calculated values should be pure. They should not be used to change state.

for instance:

import { observable,computed, action } from 'mobx';
class ObservableTodoStore {
    //Define responsive state
    @observable todos = [];
    @observable pendingRequests = 0;
    
    //Derived value
    @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}`;
    }
    
    //action
    @ction
    addTodo(task) {
        this.todos.push({
            task: task,
            completed: false,
            assignee: null
        });
    }
}

const observableTodoStore = new ObservableTodoStore();

Using decorators@

The decorator will look more friendly. Use Babel preset mobx

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

Configure in package.json after installation

Resolve asynchronous update state

class Store {
    //Defined state
    @observable listData = []
    @observable state = "pending";
    
    //Asynchronous behavior changes state, such as requesting data from the server
    @action
    async fetchProjects() {
        this.state = "pending"
        try {
            const filteredProjects = await ajaxData();
            // After await, modifying the status again requires action:
            runInAction(() => {
                this.state = "done"
                this.listData = filteredProjects
            })
        } catch (error) {
            runInAction(() => {
                this.state = "error"
            })
        }
    }
}

runInAction is a utility function. Instead of creating an action for the entire callback, run only the part of the callback that changes the state The advantage of this pattern is that it encourages you not to write actions everywhere, but to modify as many states as possible at the end of the process.

A complete example:

The whole application state management portal:

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 unified management:

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

Define single file 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();

Component binding

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

@inject('permissionStore');//Import the corresponding store
@observer
class SideMenu extends React.Component {
    constructor(props) {
        super(props);
    }
    componentDidMount() {
        const { permissionStore } = this.props;//Get store from props
        permissionStore.fetchMenus();//Asynchronous action in store
    }
    //Generate menu bar
    renderMemu = () => {
        let { menus } = this.props.permissionStore;//Get status. At this time, the data is the updated data status after asynchronously getting from the server
        return (
           ...
        )
    }
    render() {
        return (
            {this.renderMemu()}
        )
    }
}
export default SideMenu

mobx involves three core concepts: State, derivatives and Actions. It is very simple and clear to use and can be used quickly. It is a good State management tool. github star has 21K.

Keywords: Javascript React npm JSON github

Added by cityguru on Thu, 28 Nov 2019 13:11:01 +0200