在React16.6中引入了React.lazy和React.Suspense,這兩個(gè)組件,可以用來(lái)實(shí)現(xiàn)異步加載組件。
它們?cè)赗eact 16.6之前是如何實(shí)現(xiàn)的?
對(duì)于懶加載React組件最流行的庫(kù)可能是react-loadable
對(duì)比react-loadable,React.Suspense還是有一些不足。
- 加載組件缺少delay參數(shù),不能解決請(qǐng)求快速完成時(shí)的"閃爍"問(wèn)題(即使加載模塊只需要幾毫秒的時(shí)間, fallback也會(huì)被執(zhí)行,就上述代碼來(lái)說(shuō),也就是 Spinner 會(huì)閃爍一下),需要自己封裝
- 沒(méi)有內(nèi)置的加載錯(cuò)誤處理方法,需要自己去處理
- react-loadable有預(yù)加載支持,React.Lazy沒(méi)有
React.lazy 用于做Code-Splitting,代碼拆分。類(lèi)似于按需加載,渲染的時(shí)候才加載代碼。
import React, {lazy} from 'react';
const OtherComponent = lazy(() => import('./OtherComponent'));
function MyComponent() {
return (
<div>
<OtherComponent />
</div>
);
}
lazy(() => import('./OtherComponent'))使用es6的import()返回一個(gè)promise,類(lèi)似于:
lazy(() => new Promise(resolve =>
setTimeout(() =>
resolve(
// 模擬ES Module
{
// 模擬export default
default: function render() {
return <div>Other Component</div>
}
}
),
3000
)
));
React.lazy的提出是一種更優(yōu)雅的條件渲染解決方案。
之所以說(shuō)他更優(yōu)雅,是因?yàn)樗麑l件渲染的優(yōu)化提升到了框架層。
這里我們引出suspense。
當(dāng)我們組件未渲染完成,需要loading時(shí),可以這么寫(xiě):
const OtherComponent = React.lazy(() => import('./OtherComponent'));
function MyComponent() {
return (
<div>
<Suspense fallback={<div>Loading...</div>}>
<OtherComponent />
</Suspense>
</div>
);
}
在我們的業(yè)務(wù)場(chǎng)景中,OtherComponent可以代表多個(gè)條件渲染組件,我們?nèi)考虞d完成才取消loding。
只要promise沒(méi)執(zhí)行到resolve,suspense都會(huì)返回fallback中的loading。
代碼簡(jiǎn)潔,loading可提升至祖先組件,易聚合。相當(dāng)優(yōu)雅的解決了條件渲染。