繼續(xù)學(xué)習(xí)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文件在打開項目時并未加載齐苛,直到點擊了相應(yīng)路由后才進行加載翘盖。
asyncComponent 函數(shù)的實現(xiàn)方式發(fā)現(xiàn)有很多“挤洌看了一些后發(fā)現(xiàn)還是項目中的最簡潔馍驯。
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;
}
發(fā)現(xiàn)函數(shù)中寫了一個組件類,其生命周期函數(shù)componentDidMount加了es2017的async玛痊。
原理是在需要的路由組件外包裹了一層AsyncComponent 組件汰瘫,當AsyncComponent 組件渲染時,觸發(fā)componentDidMount生命周期擂煞,componentDidMount生命周期中修改了state混弥,導(dǎo)致render再次執(zhí)行。而state中存儲了需要加載的路由組件对省,在render中返回蝗拿,觸發(fā)渲染。
在組件樹中可見非異步組件直接在Route下
圖片.png
而異步加載的組件會包裹在AsyncComponent中官辽。
圖片.png
看完項目的小小功能點后蛹磺,順便復(fù)習(xí)了下webpack打包中的chunkFilename
chunkFilename: 'static/js/[name].[chunkhash:8].chunk.js',
該配置控制著chunk文件的文件名,如上圖在使用異步加載組件后多出的4個文件同仆。
學(xué)完這個后發(fā)現(xiàn)官網(wǎng)上有異步加載和代碼分割的方案react.lazy Suspense萤捆。
為react16.6加入,方法更加優(yōu)雅俗批。Suspense的fallback 屬性可設(shè)置組件切換之間的短暫空白頁面俗或,如顯示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>
);
}
下次再拜讀源碼