在开发异步加载的性能时,为进步用户体验个别会显示加载提醒,最近在应用umi
做我的项目时接触到dva-loading
,对全局和部分组件的异步加载管制还是十分不便的。
在umi中应用
装置和配置
装置 npm install dva-loading -S
后,进入src/app.js
对 dva
进行运行时配置:
import createLoading from "dva-loading"export const dva = { plugins: [createLoading()]}
models
在models
文件夹下新建count.js
文件,输出上面内容进行测试:
const delay = (ms)=>new Promise(r=>setTimeout(r,ms))export default { namespace:"count", state:{ count:1, }, effects:{ *add(action,{put,call}){ yield call(delay,1000); yield put({type:"change",payload:Math.random()}) } }, reducers:{ change(state,{payload}){ return {count:state.count+payload} } }}
组件中应用
新建Count.js
组件进行测试:
import React from "react"import { connect } from "dva"function Count({ dispatch, count, loading }) { const isLoading = loading.models.count; // 独自对 effects 管制 // const isLoading = loading.effects["count/add"] // 对多个 effects 管制 // const isLoading = loading.effects["count/add"] || loading.effects["count/minus"] || false; return ( <div> {isLoading ? <p>加载中...</p> : <p>{count}</p>} <button onClick={() => dispatch({ type: "count/add" })}>+</button> </div> )}export default connect((state) => ({ ...state.count, loading: state.loading }))(Count)
dav-loading
往全局的state
中注入了loading
,咱们能够拿到loading
对象判断组件的model
或者effect
状态。
dva-loading 源码
dva-loading
const SHOW = '@@DVA_LOADING/SHOW';const HIDE = '@@DVA_LOADING/HIDE';const NAMESPACE = 'loading';function createLoading(opts = {}) { const namespace = opts.namespace || NAMESPACE; const { only = [], except = [] } = opts; if (only.length > 0 && except.length > 0) { throw Error('It is ambiguous to configurate `only` and `except` items at the same time.'); } const initialState = { global: false, models: {}, effects: {}, }; const extraReducers = { [namespace](state = initialState, { type, payload }) { const { namespace, actionType } = payload || {}; let ret; switch (type) { case SHOW: ret = { ...state, global: true, models: { ...state.models, [namespace]: true }, effects: { ...state.effects, [actionType]: true }, }; break; case HIDE: { const effects = { ...state.effects, [actionType]: false }; const models = { ...state.models, [namespace]: Object.keys(effects).some(actionType => { const _namespace = actionType.split('/')[0]; if (_namespace !== namespace) return false; return effects[actionType]; }), }; const global = Object.keys(models).some(namespace => { return models[namespace]; }); ret = { ...state, global, models, effects, }; break; } default: ret = state; break; } return ret; }, }; function onEffect(effect, { put }, model, actionType) { const { namespace } = model; if ( (only.length === 0 && except.length === 0) || (only.length > 0 && only.indexOf(actionType) !== -1) || (except.length > 0 && except.indexOf(actionType) === -1) ) { return function*(...args) { yield put({ type: SHOW, payload: { namespace, actionType } }); yield effect(...args); yield put({ type: HIDE, payload: { namespace, actionType } }); }; } else { return effect; } } return { extraReducers, onEffect, };}export default createLoading;
@umijs/plugin-dva 接口实现
@umijs/plugin-dva 抛出的接口useSelector
能够很不便的帮忙咱们获取数据:
const { loading, count } = useSelector((stores) => ({ loading: stores.loading, count: stores.count }))
通过useDispatch
获取 dispatch:
const dispatch = useDispatch()const add = () => dispatch({ type: "count/add" })
批改状态:
import React from "react"import { useDispatch, useSelector } from "dva"function Count(props) { const dispatch = useDispatch() const add = () => dispatch({ type: "count/add" }) const { loading, count } = useSelector((stores) => ({ loading: stores.loading, count: stores.count })) const isLoading = loading.models.count return ( <div> {isLoading ? <p>loading</p> : <p>{count.count}</p>} <button onClick={add}>+</button> </div> )}export default Count
全局loading管制
通过useSelector
办法获取的stores.loading.global
,能够获取全局models
的状态是否在loading中:
import React from 'react'const {useSelector} = 'dva'import {Spin} from 'antd'const DemoPage = () => { const {loading} = useSelector(stores => ({ loading: stores.loading })) return ( <Spin spinning={loading.global}/> )}
参考:
- dva-loading
- @umijs/plugin-dva
- UmiJS开发技巧
- dva-loading 实际用法
- dva-loading 学习