React Suspense

是什么

Suspense是React在16.6版本之后添加的一个新的钩子,还有一个相对应的钩子React.lazy

16.6之前,react代码实现code-spliting一般需要第三方的插件来实现,通常是通过HOCwebpack 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来显示加载完成之前的内容。