美文网首页
react-router4.x 按需加载的实现方式

react-router4.x 按需加载的实现方式

作者: _花 | 来源:发表于2018-09-29 14:00 被阅读0次

第一种 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-importreact-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属性便无法获取。在网上没有找到解决方案,思考后发现:

  1. react-router4中每个路由也是一个组件,exact属性是从路由<Router>组件中传递给子组件的props
  2. react-loadable创建了新的懒加载组件包裹了原组件,而<Router>组件又包裹了react-loadable生成的组件
  3. 所以问题就在于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 复杂,推荐使用第二种

相关文章

网友评论

      本文标题:react-router4.x 按需加载的实现方式

      本文链接:https://www.haomeiwen.com/subject/folvoftx.html