網上關於React Router 4.0的按需加載文章有很多,大致的思路都一樣,但是其實具體實現起來卻要根據自己的實際情況來定,這里主要介紹一下我的實現方式。
主要方式是通過Route組件的render方法加載一個空的組件作為中間,通過空的組件用來加載具體的頁面js文件,然后這個組件的內部加載完成的時候就使用webpack 的 import方法動態請求js,當js請求成功后,這個空組件顯示具體的加載js內容,說起來比較晦澀,直接上代碼。
1、先看看中間組件,(由於我這里使用了Typescript, 代碼里的ts代碼不感興趣的可以直接忽略即可)
import * as React from 'react'; export namespace LoadComponentAsync { export interface Props { componentName: string } export interface State { Component: React.ReactType } } export class LoadComponentAsync extends React.Component<LoadComponentAsync.Props, LoadComponentAsync.State> { constructor(props) { super(props) this.state = { Component: null } } componentDidMount() {
// 這里使用的import進行動態加載組件 import(`../componentPublicPath/${this.props.componentName}` /* webpackChunkName: "[request]" */ ).then(Component => { this.setState({ Component: Component.default }) }) } render () { let Component = this.state.Component if (Component) { return <Component /> } else { return null } } }
是的,就是這么簡單的一個空組件。
2、Router部分怎么使用這個組件呢?
<Switch> <Route path='/some/path'} exact render={() => { return <LoadComponentAsync key={'someKey'} componentName={yourComponentName}/> }}/>
<Route path='/some/path2'} exact render={() => {
return <LoadComponentAsync key={'someKey2'} componentName={yourComponentName2}/>
}}/>
</Switch>
是的還是這么的超級簡單。
3、具體的思路上面的已經是核心代碼了,
你可能還需要配置一下東西,默認的情況你每次加載對應的路由請求的js可能是0.js 1.js 2.js這個樣子的,顯然十分丑陋,我想看他們每個js組件的具體名字是什么怎么辦呢?
首先找的你的webpack.config.js,然后,加入一個chunkFilename,
Yes, 就是這樣。然后注意到上面的import里面有個注釋了嗎
這是個啥,Magic Comments, 魔法注釋 這個webpackChunkName可以告訴webpack 每個 chunkname 是什么,這里我[request]表示的意思是每次請求的組件名稱作為chunkname ,
本文正文結束啦。
順便提一句,如果你的 Magic Comments 不生效注意你的.babelrc 或者tsconfig.json里是否有去掉注釋的邏輯(類似removeComments: true ),有的話需要關掉,然后就可以完美按需加載你的組件嘍。
注:本文出自博客園 https://home.cnblogs.com/u/mdengcc/ ,轉載請注明出處。 稍微尊重一下原創OK?