第一种 create-react-app文档给的react-router按需加载实现:
- 创建一个异步组件 AsyncComponent
import React from 'react';
export default function (getComponent) {
return class AsyncComponent extends React.Component {
static Component = null;
state = { Component: AsyncComponent.Component };
componentWillMount() {
if (!this.state.Component) {
getComponent().then(({default: Component}) => {
AsyncComponent.Component = Component
this.setState({ Component })
})
}
}
render() {
const { Component } = this.state
if (Component) {
return <Component {...this.props} />
}
return null
}
}
}
- 使用异步组件:我们将使用asyncComponent动态导入我们想要的组件。
import asyncComponent from './asyncComponent'
const Login = asyncComponent(() => load('login/login'))
const LayoutPage = asyncComponent(() => load('layout/layout'))
const NoticeDeatil = asyncComponent(() => load('noticeDetail/noticeDetail'))
export const appRouterMap = [
{path:"/login",name:"Login",component:Login,auth:false},
{path:"/web",name:"LayoutPage",component:LayoutPage,auth:false},
{path:"/notice/:id",name:"NoticeDeatil",component:NoticeDeatil,auth:false},
]
第二种 借助react-loadable来实现按需加载
利用react-loadable这个高级组件,要做到实现按需加载这一点,我们将使用的WebPack,babel-plugin-syntax-dynamic-import和react-loadable。
npm i --save-dev babel-plugin-syntax-dynamic-import
npm i --save-dev react-loadable
.babelrc:
{
“ presets ”:[ “ react ” ],
“ plugins ”:[ “ syntax-dynamic-import ]
}
import Loadable from 'react-loadable';
import Loading from './Load';
function load(component) {
return import(`$pages/${component}`)//$pages在webpack里面配置过是“./src/pages”的别名
}
const Login = Loadable({ loader: () => load('login/login'), loading: Loading});//loading属性必须有
const LayoutPage = Loadable({ loader: () => load('layout/layout'), loading: Loading,});
const NoticeDeatil = Loadable({ loader: () => load('noticeDetail/noticeDetail'), loading: Loading,});
export const appRouterMap = [
{path:"/login",name:"Login",component:Login,auth:false},
{path:"/web",name:"LayoutPage",component:LayoutPage,auth:false},
{path:"/notice/:id",name:"NoticeDeatil",component:NoticeDeatil,auth:false},
]
const {match, changeSidebar} = this.props;
if (match.isExact) {
changeSidebar('charts');
}
出现问题
使用react-loadable之前可以正常获取exact属性,而在使用react-loadable包裹需要懒加载的组件后exact属性便无法获取。在网上没有找到解决方案,思考后发现:
- react-router4中每个路由也是一个组件,exact属性是从路由<Router>组件中传递给子组件的props
- react-loadable创建了新的懒加载组件包裹了原组件,而<Router>组件又包裹了react-loadable生成的组件
- 所以问题就在于react-loadable生成的中间组件影响了react-router4的路由组件向我们的子组件传递props,所以要传递props给子组件,修正代码如下:
// Dashboard
const LoadableDashboard = Loadable({
loader: () => import('../Dashboard'),
loading: Loading
});
export class Dashboard extends React.Component {
render() {
return <LoadableDashboard {...this.props}/> // 传递props
}
}
第三种 bundle-loader 按需加载方式
安装依赖
npm install bundle-loader --save-dev
具体方式参考:
https://www.npmjs.com/package/bundle-loader
https://blog.csdn.net/dKnightL/article/details/79261867
个人感觉第三种方法 bundle-loader 复杂,推荐使用第二种