Skip to content

React Suspense

更新时间: 4/7/2020字数: 0 字

翻译:悬停、挂起。

作用 1:异步加载组件。在 react16 版本中,路由懒加载中配合 Lazy 组件一起使用 ,这也是官方在 16 版本推荐的唯一用法。

ts
const LazyChild = lazy(() => import('./child'))

<Suspense fallback={<div>loading...</div>}>
   <LazyChild />
</Suspense>

从 react18 版本后,suspense 可单独使用。

作用 2:使用Suspense来等待子组件异步数据加载完成后再渲染组件,提高用户体验。

在页面组件中,进行异步网络请求时。通常第一次渲染时,页面是没有任何数据的,数据返回后,再去重新渲染一次页面。当使用 suspense 组件后,页面就不会发生第一次的无数据时的渲染。

react 怎么知道何时渲染 fallback 的组件,何时渲染子组件?

Suspense是根据捕获子组件内的异常来实现决定展示哪个组件的。类似于ErrorBoundaryErrorBoundary是捕获 Error 时就展示回退组件,而Suspense 捕获到的 Error 需要是一个Promise对象。

推荐:使用第三方框架提供的能力使用 Suspense 请求数据。

抛出一个 Promise 时,react 执行过程:

  1. 挂起渲染: 首先,React 会暂停当前组件树的渲染。等待 Promise 解析完成。
  2. 显示 Fallback: 在等待期间,React 会展示Suspense组件提供的 fallback。
  3. Promise 解析: 当子组件内部的 Promise 解析完成(即数据加载成功或错误处理完毕),React 会收到通知。
  4. 重新渲染: 接着,React 会重新尝试渲染之前挂起的组件树。这次,由于之前阻塞渲染的 Promise 已经完成,子组件应该能够正常渲染而不抛出 Promise 了。因此,整个组件树会从Suspense节点开始往下重新渲染,展示最新的数据。
ts
export default () => {
  if (!data) {
    throw new Promise((resolve) => {
      setTimeout(() => {
        data = '数据'
        resolve()
      }, 2000)
    })
  }

  console.log('子组件 ---rerender')
  return <div>子组件 data is {data}</div>
}

作用 3:服务端渲染

Released under the MIT License.