使用 mobx-react-stores 开发 react 应用
原文地址:https://acme.top/mobx-react-stores-doc 前言mobx-react-stores 是为了方便将 antd pro 改为使用 mobx 而开发的,里面的思路和代码大量的参考了 dva 和 umi 的实现 安装npm i mobx-react-stores 使用获取 import {stores} from 'mobx-react-stores'; 状态管理mobx-react-stores 可以用作状态管理,也是其最核心的目的,接口设计的比较简单,主要就两个:
监听加载状态
import {loadingStore} from 'mobx-loading' mobx-react-stores 默认集成了 mobx-loading,作为 stores 的内置属性,namespace 为 const {loading} = stores;
// 通过 actions 获取指定 namespace/action 的当前加载状态 loading.actions['goods/fetchList'] // 通过 models 获取指定 namespace 的当前加载状态 // namespace 下任何 action 加载状态为 true,则此 namespace 的加载状态即为 true loading.models.goods // 通过 global 获取全局的加载状态 // 只要任何一个 model 的状态为 true,则 global 的状态即为 true loading.global // 从 mobx-react-stores 和 mobx-loading 中都可以获取 namespace 装饰器 // 用作 class,方便向 class 中注入 namespace 属性 import {namespace} from 'mobx-loading'; import {namespace} from 'mobx-react-stores';
// 获取 namespace 和 loading 装饰器 import {namespace,loading} from 'mobx-react-stores'; import {fetchRandomUser} from "@/services/demo"; // 默认会为 class 添加 namespace 属性,值为将 class 类名转换为首字母小写的字符串 // 此处 namespace 值为 randomUser @namespace class RandomUser { user; message; // 通过 loading 装饰器,向 loadingStore 中注入当前 action 的加载状态 @loading fetchUser = async () => { this.user = null; this.message = null; const response = await fetchRandomUser().catch(this.onRejected); if (response.results) { const user = response.results[0]; this.change({ user: { name: `${user.name.first} ${user.name.last}`,email: user.email,picture: user.picture.large },message: null }); } } change = ({user,message}) => { this.user = user; this.message = message; } onRejected = (e) => { return { status: 500,message: e.message } } } export default new RandomUser(); // -----------------------RandomUser.js-------------------------------- import React from 'react'; import {inject} from 'mobx-react' @inject(({stores: {dispatch,loading,randomUser}}) => { return { dispatch,randomUser,loading: loading.models.randomUser } }) class RandomUser extends React.PureComponent { onFetchUser = () => { const {dispatch} = this.props; dispatch({ type: 'randomUser/fetchUser' }) } render() { const {loading,randomUser} = this.props; if (loading) { // do someting }else{ const {user,message} = randomUser; // do someting } } } export default RandomUser;
路由管理为了方便管理路由以及向 stores 中注入 model,mobx-react-stores 提供了类似 umi 管理路由的方法,不过没有像 umi 那样去生成临时文件,而是更直接的方式
路由示例 export default [ // user { path: '/user',// 布局文件 component: () => import('./layouts/UserLayout'),LoadingComponent = require('./components/PageLoading').default, Routes: [require('./pages/Authorized').default],authority: ['admin','user'],routes: [ // 从 /user 重定向到 /user/login {path: '/user',redirect: '/user/login'},{path: '/user/login',name: 'login',component: () => import('./pages/User/Login')},{ name: 'register',path: '/user/register',models: () => [import('./pages/User/models/register')],component: () => import('./pages/User/Register') },{ name: 'register.result',path: '/user/register-result',component: () => import('./pages/User/RegisterResult'),},],} ]
使用路由 import {formatterRoutes,renderRoutes} from 'mobx-react-stores'; import router from './default.router.js'; // ... do someting // 格式化 const routes = formatterRoutes(this.router,this.stores); // 渲染路由 let children = renderRoutes(routes); return ( <Router history={history}> {children} </Router> ); // ... do someting 国际化mobx-react-stores 推荐使用 react-intl 来管理国际化 注入 Locale import {stores,Locale} from 'mobx-react-stores'; // ... do someting // 可参考 Antd Pro const translations = { 'en-US': { messages: { ...require('../locales/en-US.js').default,locale: 'en-US',antd: require('antd/lib/locale-provider/en_US'),data: require('react-intl/locale-data/en'),momentLocale: '','zh-CN': { messages: { ...require('../locales/zh-CN.js').default,locale: 'zh-CN',antd: require('antd/lib/locale-provider/zh_CN'),data: require('react-intl/locale-data/zh'),momentLocale: 'zh-cn',// ... 其他语言包 }; // 注入 stores.add(new Locale('zh-CN',translations)); // ... do someting 切换语言 stores.locale.change('zh-CN'); // 或者 dispatch({ type: 'locale/change',payload: 'zh-CN' }); 集成为了简化开发,方便使用 国际化、history 等,mobx-react-stores 提供了集成好的接口 使用示例 在 // 兼容 IE9、IE10 ~ 如果需要的话请解开封印 // import 'react-app-polyfill/ie9'; // import 'react-app-polyfill/stable'; import React from 'react'; import {LocaleProvider} from 'antd'; import {app} from 'mobx-react-stores'; import get from 'lodash/get'; import './utils/axios'; // 初始化拦截器 import './global.less'; import * as serviceWorker from './serviceWorker'; app.stores = require('./models').default; app.router = require('./default.router').default; app.defaultLoadingComponent = require('./components/PageLoading').default; // 渲染时回调,方便一些额外的操作,比如注入 antd 的国际化 app.renderCallback = (children) => { const {locale} = app.stores; const antd = get(app.stores,'locale.translation.antd',undefined); if (antd) { return ( <LocaleProvider locale={antd.default || antd}> {children} </LocaleProvider> ); } return children; }; app.render(document.getElementById('root')); // If you want your app to work offline and load faster,you can change // unregister() to register() below. Note this comes with some pitfalls. // Learn more about service workers: https://bit.ly/CRA-PWA serviceWorker.unregister(); 集成后
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |