是什么
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来显示加载完成之前的内容。