一個簡單,可拓展的狀態管理工具
npm install mobx --save
狀態是驅動應用的數據,狀態的改變會影響視圖。react
import {observable, autorun} from 'mobx'; var todoStore = observable({ /* 一些觀察的狀態 */ todos: [] });
任何源自狀態而且不會再有任何進一步的相互做用的東西就是衍生。git
import {observable, autorun} from 'mobx'; var todoStore = observable({ /* 一些觀察的狀態 */ todos: [], /* 衍生值 */ get completedCount() { return this.todos.filter(todo => todo.completed).length; } });
注意:衍生值必須是純函數
動做是一段能夠改變狀態的代碼。用戶事件、後端數據推送、預約事件、等等。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中配置後端
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。