网上关于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?