异步加载路由原理

基本原理

目录结构

 src
	util
		asyncRouter.js
	a.js
	b.js

组件a

const a = () => {
  return (
    <div >
      a
    </div>
  );
}

export default a

组件b

const b = () => {
  return (
    <div >
      b
    </div>
  );
}

export default b

asyncRouter.js


// 将module.default和module整合成统一的数组。
const m = module => module.default || module
const esModule = (module) => module.map(m)

const asyncRouter = async(comp) => {
  // 异步请求
  const compData = await Promise.all([
    comp()
  ])
  // 修复数据结构
  const Cmp = esModule(compData)
  console.log(Cmp)
  return Cmp
}

// 异步加载路由模块
asyncRouter(() => import('../a'))
asyncRouter(() => import('../b'))

export default asyncRouter

进一步完善成基本的路由助手函数

import {Component} from 'react'
// 将module.default和module整合成统一的数组。
const m = module => module.default || module
const esModule = (module) => {
  // 分是否是数组来处理
  if(Object.prototype.toString(module) === '[Object array]') {
    return module.map(m)
  }
  return m(module)
}
function asyncRouter(comp) {
  // 返回组件类,到路由上注入
  return class AsyncRoute extends Component {
    constructor() {
      super()
      this.state = {
        Cmp: null
      }
    }
    loadData = async() => {
      // 异步请求
      const [compData] = await Promise.all([
        comp()
      ])
      // 修复数据结构
      const Cmp = esModule(compData)
      this.setState({ // 更新组件
        Cmp
      })
    }
    componentDidMount() {
      this.loadData() // 加载数据
    }
    render() {
      const {Cmp} = this.state
      return Cmp && <Cmp /> // 返回组件
    }
  }
}

export default asyncRouter

index.js加入路由

import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import { BrowserRouter } from "react-router-dom";
ReactDOM.render(
  <React.StrictMode>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </React.StrictMode>,
  document.getElementById("root")
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

App.js加入导航链接和路由组件组

import logo from './logo.svg';
import './App.css';
import asyncRouter from './utls/asyncRouter'
import {Route, Switch, Link} from 'react-router-dom'
// 这块还能再抽离出去单独管理。
const a = asyncRouter(() => import('./a'))
const b = asyncRouter(() => import('./b'))

function App() {
  return (
    <div className="App">
        <ul>
          <li>
            <Link to='/a'>a</Link>
          </li>
          <li>
            <Link to='/b'>b</Link>
          </li>
        </ul>
        <Switch>
          <Route path='/a' component={a} />
          <Route path='/b' component={b} />
        </Switch>
      </div>
  );
}
export default App;

总结:异步加载路由主要使用了import实时载入以及promise的控制,最后利用高阶函数里面的闭包写法返回类来输出成组件喂给路由的component属性。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值