Suspense
和
React.lazy()
,進行代碼分割和懶加載組件:
React
官網有相關代碼分離的說明,這裏再也不贅述,使用 import()
動態導入會更加有利於代碼的分離。react
關於import()
語法,若是你使用CRA(create-react-app)搭建的項目,能夠直接使用這個語法。若是是本身從零開始搭建的項目,須要babel
的插件 babel-plugin-syntax-dynamic-import
;shell
yarn add babel-plugin-syntax-dynamic-import
or
npm install babel-plugin-syntax-dynamic-import
複製代碼
.babelrc 或者 babel.config.js 中增長:npm
{
"plugins": ["syntax-dynamic-import"]
}
複製代碼
React.lazy()
容許你渲染一個動態引入的組件像普通組件同樣執行;json
React.lazy
可接受一個返回Promise
的調用import()
的function
,這個promise
最後resolve
一個默認導出當前組件。promise
通常寫法:服務器
import React, {lazy} from "react";
// 默認後綴 .jsx
const App = lazy(()=> import("../pages/App"));
const About = lazy(()=> import("../pages/About"));
// 路由配置
const routerConfig = [
{
path: '/',
component: App
},
{
path: '/about',
component: About
},
];
function AppRouter() {
return (
<Suspense fallback={<div>Loading...</div>}>
<Router basename="/">
<Switch>
{routerConfig.map((n, index) => {
return <Route path={n.path} exact component={n.component} key={index}></Route>;
})}
</Switch>
</Router>
</Suspense>
);
}
export default AppRouter;
複製代碼
Lazy
組件須要反之在 Suspense
組件內部, Suspense
提供一個 fallback
內容填充,當正在懶加載組件的時候,好比加個loading;babel
咱們下面對lazy進行二次封裝:app
// lazy load
const lazyLoad = path =>
lazy(() => {
return new Promise(resolve => setTimeout(resolve, 1 * 1000)).then(() => import(`../pages/${path}`)).catch(() => import('../components/Error'));
});
//這個方法須要注意的一點,這個 path 不能直接傳`相對路徑`相似 `../pages/App`,
//會找不到組件,因此最好只傳過來一個組件名字,而後內部拼接相對路徑
//另外在後面加了一個Promise的reject狀態處理,若是組件加載錯誤,將會默認加載Error組件;
import Loading from '@c/Loading';
const App = lazyLoad('App');
const About = lazyLoad('About');
function AppRouter() {
return (
<Suspense fallback={<Loading />}>
{/* 只有當你的應用部署到服務器的二級目錄的時候,才須要設置basename */}
{/* <Router basename="/"> */}
<Router basename="/">
<Switch>
{routerConfig.map((n, index) => {
return <Route path={n.path} exact component={n.component} key={index}></Route>;
})}
</Switch>
</Router>
</Suspense>
);
}
export default AppRouter;
複製代碼
這樣就完成了懶加載路由的簡單封裝。spa