1. 借助三方库 react-loadable
Loadable 是一个高阶组件
高阶组件(简单来说,就是把组件作为输入的组件。高阶函数就是把函数作为输入的函数。在 React 里,函数和组件有时是一回事
import React from 'react';
import Loadable from 'react-loadable';
function Loading() {
return <div>Loading.....</div>
}
const LoadableComponent = Loadable({
loader: () => import('./OtherComp3'),
loading: Loading,
});
function App() {
return (
<LoadableComponent/>
);
}
export default App;
2. React.lazy() 和 Suspense
React.lazy 功能允许将动态导入呈现为常规组件。
之前的做法:
import OtherComp from './OtherComp'
function App() {
return (
<div>
<OtherComp/>
</div>
);
}
export default App;
之后:
import React, { Suspense, lazy } from 'react';
const OtherComp2 = lazy(() => import('./OtherComp2'))
function App() {
return (
<Suspense fallback={<div>loading....</div>}>
<OtherComp2/>
</Suspense>
);
}
export default App;
React.lazy 所接收的参数必须是一个 动态调用的 import()函数且返回一个 Promise 解析为默认导出为React组件的模块。
为了给用户更好的体验,我们可以借助Suspense组件的 fallback 属性定义加载前的一些交互,fallback属性接受任何React元素。可以将Suspense组件放在 lazy组件层级上面的任意位置,同时Suspense组件可以包含多个lazy组件。
import React, { Suspense, useState, lazy } from 'react';
import OtherComp from './OtherComp'
const OtherComp2 = lazy(() => import('./OtherComp2'))
const OtherComp3 = lazy(() => import('./OtherComp3'))
function Loading() {
return <div>Loading.....</div>
}
function App() {
const [isShow, setIsShow] = useState(false)
const handleClick = () => {
setIsShow(true)
}
let lazyComps = null
if (isShow) {
lazyComps = <Suspense fallback={Loading()}>
<OtherComp2 name="lazy加载" />
<OtherComp3 name="lazy加载" />
</Suspense>
}
return (
<>
<Suspense fallback={<div>Loading.....</div>}>
<div className="App">
<div>
<OtherComp name="正常加载" />
</div>
<button onClick={handleClick}>加载组件 Comp 2 和 Comp3</button>
<div>
{lazyComps}
</div>
</div>
</Suspense>
</>
);
}
export default App;
3. 结合 React-Router
引入 reacct-router-dom 库
npm install react-router-dom
import React, { Suspense, lazy } from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'
import OtherComp from './OtherComp'
const OtherComp2 = lazy(() => import('./OtherComp2'))
function App() {
return (
<Router>
<Suspense fallback={<div>Loading.....</div>}>
<Switch>
<Route exact path="/pageA" component={OtherComp} />
<Route exact path="/pageB" component={OtherComp2} />
</Switch>
</Suspense>
</Router>
);
}
export default App;