关于 React.lazy 和 Suspense (서스펜스)。
对于 suspense 真的很陌生。但是翻译成中文是 悬念 。嘿嘿嘿,兴趣就来了呢。
对于懒加载之前用的都是 react-loadable 这个包
并且用的不是很多,只是在路由的时候用到过。
今天早上在公众号看到一篇文章《React的未来:与Suspense共舞》
当时反应是 Suspense 是什么?
然后进去看了看关于 React.lazy ,这个东西在刚出的时候有过了解(一点),但是一直没有真的用过。
所以先挖个坑。
-> 官方文档
-> 知乎 - React lazy/Suspense使用及源码解析
上面的两篇文章提供了很多帮助。
定义和使用
The React.lazy function lets you render a dynamic import as a regular component.
React.lazy 提供的服务就是懒加载 ( 动态加载
官方文档中描述到,React.lazy( ) 的参数是一个函数,该函数动态调用 import( )。而返回值是一个 Promise ,而这个 Promise 会 resolve 一个默认输出( default export )的组件。
举一个官方的例子:
1 | const OtherComponent = React.lazy(() => import('./OtherComponent')); |
If the module containing the OtherComponent is not yet loaded by the time MyComponent renders, we must show some fallback content while we’re waiting for it to load - such as a loading indicator. This is done using the Suspense component.
Suspense 帮助当动态加载的组件没有渲染好时显示 loading 信息。
再举个官方的例子:
1 | const OtherComponent = React.lazy(() => import('./OtherComponent')); |
在上面的例子中,可以看到 Suspense 组件安置在动态加载的组件之上的任意位置, Suspense 组件中可以包含多个动态加载的组件。
对比
对于以前实现异步加载,都是使用的 react-loadable 这个插件。
举个例子:
1 | import Loadable from 'react-loadable'; |
Loadable( ) 函数实现的功能与 React.lazy 和 Suspense 类似。
Loadable( ) 参数的 loader 对象的值与 React.lazy 的参数一致,loading 对象的功能与 Suspense 一致。
源码阅读
React.lazy 和 Suspense 的使用非常简单。
源码的代码量也比较的少。
1 | export function lazy<T, R>(ctor: () => Thenable<T, R>): LazyComponent<T> { |
lazy 函数返回的就是一个对象,通过源码可以看到 lazyType 的类型是 LazyComponent
$$typeof 就是常见的对象类型;
_ctor 在源码中可以看类型是 () => Thenable<T, R> ,而从 Thenable 的源码
1 | export type Thenable<T, R> = { |
可以看出 _ctor 记载了产生一个 thenable 对象的方法。
thenable 指具有 then 方法的对象。
对于 _status 和 _result。
React uses these fields to store the result.
_status 就是 promise 的执行状态,-1 是默认值,0 是 pending ,1 是 resolved, 2 是 rejected。
_result 则用于存储懒加载异步函数执行的结果。