react-loadable的使用(封装)
当组件还在加载中的时候显示一个页面,一般是一张动图gif表现出加载中的效果
asyncLoader.tsx
import Loadable from 'react-loadable';
// import Toast from '_component/toast'
import * as React from 'react';
import PageLoader from '../pageLoader/index';
const asyncLoader = (fn: any) => {
return Loadable({
loader: fn,
loading: ToastTrue,
delay: 100
});
};
function ToastTrue(params: any) {
if (params.pastDelay) {
return <PageLoader />;
} else {
return null;
}
}
export default asyncLoader;
loader是加载完成以后显示的组件,loading是还在加载中显示pageLoader组件
delay:loading 的组件有一个 pastDelay prop的属性,只有在真正用到的组件花了比设定的 delay更长的时间加载的时候,它的值才会是 true(才会显示提示的 loading 组件),这个属性的作用是为了避免加载组件时的闪烁,默认值是200ms
pageLoader.tsx
import * as React from 'react';
import * as style from './style.css';
import * as LoadingImg from '../../../assects/images/load-source.gif';
interface Props {
text?: string;
}
interface State {
isNetError: boolean;
}
class PageLoader extends React.Component<Props, State> {
timer: any = 0;
constructor(props: Props) {
super(props);
this.state = {
isNetError: false
};
}
reloadPage() {
let search = window.location.search;
if (search.length > 0) {
window.location.href = window.location.href + '&_t=' + new Date().getTime();
} else {
window.location.href = window.location.href + '?_t=' + new Date().getTime();
}
}
componentDidMount() {
this.timer = setTimeout(() => {
this.setState({ isNetError: true });
}, 10000);
}
componentWillUnmount() {
clearTimeout(this.timer);
}
onClickReload = () => {
this.reloadPage();
};
render() {
return (
<div>
{this.state.isNetError ? (
<div className={style.errorContainer}>
<p className={style.errorTip}>网络加载失败</p>
<p className={style.refreshTip}>请再次刷新或检查网络</p>
<div className={style.refreshBtn} onClick={this.onClickReload}>
点击刷新
</div>
</div>
) : (
<div className={style.loadingContainer}>
<div>
<img src={LoadingImg} />
<p>{this.props.text || '页面加载中,请稍候...'}</p>
</div>
</div>
)}
</div>
);
}
}
export default PageLoader;
pageLoader中的state参数isNetError,同时设置了setTimeout,如果用户加载了十秒还是没有加载出页面,就是会提示用户刷新网络
style.css
.errorContainer {
padding-top: 70px;
text-align: center;
}
.errorTip {
font-weight: bold;
font-size: 18px;
margin-bottom: 2px;
}
.refreshTip {
margin-bottom: 24px;
letter-spacing: 1px;
font-size: 16px;
color: #cdcdcd;
}
.refreshBtn {
width: 160px;
line-height: 43px;
letter-spacing: 1px;
background: #cdcdcd;
color: #fff;
border-radius: 10px;
margin: 0 auto;
}
.loadingContainer {
margin: 0 auto;
width: 100%;
max-width: 480px;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
color: #cdcdcd;
text-align: center;
background: #fff;
font-size: 14px;
}
.loadingContainer div {
margin-top: -50px;
}
.loadingContainer img {
width: 150px;
height: 130px;
}
最后是封装好的加载页面的使用:
import asyncLoader from "./component/public/asyncLoader/index"
const Manage = asyncLoader(()=>import("./pages/manage/manage"))