在React16.6中引入了React.lazy和React.Suspense,这两个组件,可以用来实现异步加载组件。
它们在React 16.6之前是如何实现的?
对于懒加载React组件最流行的库可能是react-loadable
对比react-loadable,React.Suspense还是有一些不足。
- 加载组件缺少delay参数,不能解决请求快速完成时的"闪烁"问题(即使加载模块只需要几毫秒的时间, fallback也会被执行,就上述代码来说,也就是 Spinner 会闪烁一下),需要自己封装
- 没有内置的加载错误处理方法,需要自己去处理
- react-loadable有预加载支持,React.Lazy没有
React.lazy 用于做Code-Splitting,代码拆分。类似于按需加载,渲染的时候才加载代码。
import React, {lazy} from 'react';
const OtherComponent = lazy(() => import('./OtherComponent'));
function MyComponent() {
return (
<div>
<OtherComponent />
</div>
);
}
lazy(() => import('./OtherComponent'))使用es6的import()返回一个promise,类似于:
lazy(() => new Promise(resolve =>
setTimeout(() =>
resolve(
// 模拟ES Module
{
// 模拟export default
default: function render() {
return <div>Other Component</div>
}
}
),
3000
)
));
React.lazy的提出是一种更优雅的条件渲染解决方案。
之所以说他更优雅,是因为他将条件渲染的优化提升到了框架层。
这里我们引出suspense。
当我们组件未渲染完成,需要loading时,可以这么写:
const OtherComponent = React.lazy(() => import('./OtherComponent'));
function MyComponent() {
return (
<div>
<Suspense fallback={<div>Loading...</div>}>
<OtherComponent />
</Suspense>
</div>
);
}
在我们的业务场景中,OtherComponent可以代表多个条件渲染组件,我们全部加载完成才取消loding。
只要promise没执行到resolve,suspense都会返回fallback中的loading。
代码简洁,loading可提升至祖先组件,易聚合。相当优雅的解决了条件渲染。