基本原理
目录结构
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属性。