是什么
Suspense是React在16.6版本之后添加的一个新的钩子,还有一个相对应的钩子React.lazy。
在16.6之前,react代码实现code-spliting一般需要第三方的插件来实现,通常是通过HOC与webpack dynamicImport来实现的,例如react-loadable。现在16.6之后代码分割可以通过Suspense来实现。
示例代码
// 需要异步加载的组件 Date.jsx
import React from 'react';
import moment from 'moment';
const Date = () => <h1>{moment().format('YYYY-MM-DD')}</h1>;
export default Date;
// 使用
import React, { Suspense, useState } from 'react';
import './App.css';
const Date = React.lazy(() => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(import('./Date'));
}, 1000);
});
});
function App() {
const [dateVisible, setDateVisible] = useState(false);
return (
<div className="App">
<button onClick={(e) => setDateVisible(!dateVisible)}>tigger date component</button>
<Suspense fallback={<div>date loading...</div>}>
{ dateVisible ? <Date /> : null }
</Suspense>
</div>
);
}
说明
看上面代码可以发现通过React.lazy来动态加载组件,然后通过Suspense包裹这个异步组件。
有点迷的是,为啥要Suspense,直接React.lazy就是异步加载组件了啊。其实这个和React的同步渲染有关,上述代码为例,在dataVisible为真的时候,开始渲染Date组件,但是由于Date通过React.lazy动态加载,这个时候Date还没加载完,就会抛出异常出来,这个时候就会报错,Suspense的作用就是捕获这个异常不报错,并且通过fallback这个props来显示加载完成之前的内容。