Use mobx-react-stores react Application Development

Original Address: https://acme.top/mobx-react-stores-doc

Foreword

mobx-react-stores in order to facilitate antd pro developed using mobx, which codes a large number of ideas and with reference to the realization and umi of dva

installation

npm i mobx-react-stores

use

Gets storesinstance of an object

import {stores} from 'mobx-react-stores';

State Management

mobx-react-stores can be used as state management, but also its core purpose, interface design is relatively simple, mainly on two:

  1. stores.add (Model: Object | Promise, namespaceAlias: null | String) - used to storesinject to be managed modelobjects
  • Parameter modelif an object must contain a string of type namespaceattribute, which is used as a storesunique identifier, which is the storesname of the attribute
  • Parameter modelmay be a Promisetarget, Promiseyou must return a string type namespaceattribute
  • Parameters namespaceAliasOptionally, used to modelaliases, if present modelmay not contain namespaceproperties
  1. dispatch ({type, payload}) - similar dvato dispatch, through for namespace/actionquick access to this type modelfunctions in an object
  • The parameter typeis a string type, the formatnamespace/action
  • Parameters payloadof any type, optionally, used to pass parameters to the called function in namespace/actionthe parameter is a function of the receivedpayload
  • dispatch Generally injected directly into the context, to facilitate assembly call

Monitor the loading state

mobx-loadingDva-loading can achieve a similar effect, and the model easy to monitor the execution state of the action, to reduce the component developers show hideoperate

  • Get loadingStore object's methods
import {loadingStore} from 'mobx-loading'

mobx-react-stores default integrated mobx-loading, as a built-in attribute stores, for the namespace loading, the objects may be obtained directly from the stores in loadingStore

const {loading} = stores;
  • Use
// 通过 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';
  • Examples of Use
// 获取 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;
  • @loading (names: String | Array | null) - loading acting on the decorative function in the model, and may receive an array of strings parameters

  • For example: @loading ( 'randomUser / fetchList'), @ namespace ([ 'randomUser', 'fetchList']) with the results of the above sample code as

  • loadingDecorator preferably used class name of the current namespace attribute and the function (first letter lowercase) generated uniquely identifies the action, without the namespace attribute class name (first letter lowercase) use. No reference example loading door is a function of the load state may be loadingStore.actions['randomUser/fetchList']achieved

The above example is loading decorators, and stores.loading different. stores.loading is injected property after stores loadingStore

Routing Management

In order to facilitate management and routing injection model in the stores, mobx-react-stores offer similar umi management routing method, but not as to generate temporary files like umi, but a more direct way

Suggested srcthe new catalog default.router.jsfile to store the route, if the module number and complexity of the routing can be dispersed to each module to the file is then polymerized

Routing Example

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'),
            },
        ],
    }
]
  • name - the name of the route, will generate a menu for the Build menu, name and path of ~ Antd Pro there are so defined
  • path - the path routing
  • Models - Model collection of objects, supports demand loading, loaded together with the component, support: () => [import('xxx/model1'), import('xxx/model2')], () => import('xxx/model1'), [() => import('xxx/model1'), () => import('xxx/model2')]and other forms. The main sub facilitate routing of models and an array of superior routing models were merged, some of the common models can be placed in higher-level routing, ease of management.
  • the Component - component, if there are lower-level routing, it is the lower routing layout files, supports asynchronous demand loading (must provide a function like this:()=>import('xxxx'))
  • LoadingComponent - load performance component when the asynchronous demand loading assembly
  • The Routes - easy to customize permissions check routing, refer to Antd Pro to achieve
  • Authority - required permissions to access routes, for permission to check, refer to Antd Pro to achieve
  • routes - sub-route set

Use routing

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

globalization

mobx-react-stores recommended react-intl managing international

Injection 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

Switch language

stores.locale.change('zh-CN');

// 或者

dispatch({
    type: 'locale/change',
    payload: 'zh-CN'
});

integrated

To simplify development, facilitate the use of international, history, etc., mobx-react-stores provides an integrated interface to good

Examples of Use

In the srcdirectory new index.jsfile as a file entry

// 兼容 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();

After integration

  • stores will be obtained intl, routingtwo objects, and operations may be used to route international
  • intl is an example of an object after the react-intl injection, may be used intl.formatMessage()and other functions
  • routing may be implemented routing.push(), routing.replace()like routing operations

Guess you like

Origin www.cnblogs.com/niqingyang/p/11306407.html
Recommended