继续学习github高赞项目react-pxq
项目router中引入了路由组件,使用了异步加载的模式
import asyncComponent from '@/utils/asyncComponent';
const record = asyncComponent(() => import("@/pages/record/record"));
const helpcenter = asyncComponent(() => import("@/pages/helpcenter/helpcenter"));
const production = asyncComponent(() => import("@/pages/production/production"));
const balance = asyncComponent(() => import("@/pages/balance/balance"));
异步加载组件后,打包后项目文件多了几个chunk.js。
图片.png
这些js文件在打开项目时并未加载,直到点击了相应路由后才进行加载。
asyncComponent 函数的实现方式发现有很多。看了一些后发现还是项目中的最简洁。
export default function asyncComponent(importComponent) {
class AsyncComponent extends Component {
constructor(props) {
super(props);
this.state = {
component: null
};
}
async componentDidMount() {
const { default: component } = await importComponent();
this.setState({component});
}
render() {
const C = this.state.component;
return C ? <C {...this.props} /> : null;
}
}
return AsyncComponent;
}
发现函数中写了一个组件类,其生命周期函数componentDidMount加了es2017的async。
原理是在需要的路由组件外包裹了一层AsyncComponent 组件,当AsyncComponent 组件渲染时,触发componentDidMount生命周期,componentDidMount生命周期中修改了state,导致render再次执行。而state中存储了需要加载的路由组件,在render中返回,触发渲染。
在组件树中可见非异步组件直接在Route下
图片.png
而异步加载的组件会包裹在AsyncComponent中。 图片.png
看完项目的小小功能点后,顺便复习了下webpack打包中的chunkFilename
chunkFilename: 'static/js/[name].[chunkhash:8].chunk.js',
该配置控制着chunk文件的文件名,如上图在使用异步加载组件后多出的4个文件。
学完这个后发现官网上有异步加载和代码分割的方案react.lazy Suspense。
为react16.6加入,方法更加优雅。Suspense的fallback 属性可设置组件切换之间的短暂空白页面,如显示loading
import React, { Suspense } from 'react';
const OtherComponent = React.lazy(() => import('./OtherComponent'));
const AnotherComponent = React.lazy(() => import('./AnotherComponent'));
function MyComponent() {
return (
<div>
<Suspense fallback={<div>Loading...</div>}>
<section>
<OtherComponent />
<AnotherComponent />
</section>
</Suspense>
</div>
);
}
下次再拜读源码
网友评论