为什么要使用异步加载组件
因为项目中存在一些不必要的状态重复计算和UI重复渲染,为了做出优化,所有就有了异步加载组件
使用方法
AsyncComponent.js(工具方法)
import React, { Component } from "react";
export default function asyncComponent(importComponent) {
class AsyncComponent extends Component {
constructor(props) {
super(props);
this.state = {
component: null
};
}
componentDidMount() {
importComponent().then((mod) => {
this.setState({
// 同时兼容ES6和CommonJS的模块
component: mod.default ? mod.default : mod
});
});
}
render() {
const C = this.state.component;
return C ? <C {...this.props} /> : null;
}
}
return AsyncComponent;
}
开始使用
import asyncComponent from 'asyncComponent.js的相对路径';
// 使用异步组件加载工具方法加载组件
const AsyncHome = asyncComponent(() => import('../Home'));
const AsyncLogin = asyncComponent(() => import('../Login'));
// 使用异步组件
<BrowserRouter>
<Switch>
<Route path='/' component={AsyncHome} />
<Route path='/login' component={AsyncLogin} />
<Route path='/posts' component={AsyncHome} />
</Switch>
</BrowserRouter>
改进版本
在上个版本的异步组件中,还可以对其进行优化,这里我们通过创建一个高阶组件内重写组件的 shouldComponentUpdate 方法,如果 Route传递的 location 属性未发生改变(也就是在同一个页面),就返回 false ,从而阻止组件继续更新,然后使用这个高阶组件报过没一个要在Route 中使用的组件
connectRoute.js(工具方法)
import React from "react";
export default function connectRoute(WrappedComponent) {
return class ConnectRoute extends React.Component {
shouldComponentUpdate(nextProps) {
return nextProps.location !== this.props.location;
}
render() {
return <WrappedComponent {...this.props} />;
}
};
}
开始使用
import asyncComponent from "../../utils/AsyncComponent";
import connectRoute from "../../utils/connectRoute";
const AsyncHome = connectRoute(asyncComponent(() => import("../Home")));
const AsyncLogin = connectRoute(asyncComponent(() => import("../Login")));
<BrowserRouter>
<Switch>
<Route exact path="/" component={AsyncHome} />
<Route path="/login" component={AsyncLogin} />
<Route path="/posts" component={AsyncHome} />
</Switch>
</BrowserRouter>