在开发异步加载的性能时,为进步用户体验个别会显示加载提醒,最近在应用 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 学习