一个简单,可拓展的状态管理工具
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。