内容简介:如同字面意思,Suspense 让组件遇到异步操作时进入“悬停”状态,等异步操作有结果时再回归正常状态。异步操作简单归为两类:异步加载代码就是所谓的
如同字面意思,Suspense 让组件遇到异步操作时进入“悬停”状态,等异步操作有结果时再回归正常状态。
异步操作简单归为两类:
- 异步加载代码
- 异步加载数据
异步加载代码
异步加载代码就是所谓的 code splitting
,实现起来就像是这样:
import React, {lazy, Suspense} from 'react'; const OtherComponent = lazy(() => import('./OtherComponent')); function MyComponent() { return ( <Suspense fallback={<div>Loading...</div>}> <OtherComponent /> </Suspense> ); } 复制代码
值得一提的是目前版本 (截止至 react@16.8) 还不支持服务端渲染,但还是会在以后的版本上支持的。
异步加载数据
Suspense 异步加载数据截止到目前都是不稳定的版本,根据React 16.x Roadmap,大概到2019年中期发布稳定版本,但是 React 官方提供了一个独立的包 react-cache
,使用它结合 react@16.6.0
可以让我们提前感受一下 Suspense 异步加载数据。
import { unstable_createResource } from 'react-cache'; const getSomething = (something) => new Promise((resolve) => { setTimeout(() => { resolve(something); }, 1000); }) const resource = unstable_createResource((id) => getSomething(id)) function Demo() { const data = resource.read(666) return ( <div>{data}</div> ); } 复制代码
细谈 Suspense
在上面的实例中,Suspense 组件传入了 fallback
属性,这个属性用于显示加载中的页面,就是俗称的 loading 咯。
那么我们在想一个问题,如果一个异步请求数据的过程非常快,这样会使得加载中画面一闪而过,导致闪屏。
Suspense 针对这种情况给出解决方案 maxDuration
属性:
<Suspense fallback={<Spinner />} maxDuration={500}> // ... </Suspense> 复制代码
当异步获取数据的时间大于 maxDuration
时间时展示 fallback
,否则直接展示数据。
需要注意的是 maxDuration
属性只有在 Concurrent Mode
下才能生效,在以往的 Sync 模式下 maxDuration
始终为0, 具体使用简单给出一个实例:
// ReactDOM.render(<App />, document.getElementById('root')); ReactDOM .unstable_createRoot(document.getElementById('root')) .render( <React.unstable_ConcurrentMode> <App /> </React.unstable_ConcurrentMode> ); 复制代码
原理
Suspense 的实现原理颇有争议。
当我们在 render 内写异步请求数据时会抛出一个异常,当然它应该是一个 promise
,这个异常会被 Suspense 内一个新的生命周期 ComponentDidCatch
捕获到,在这个生命周期内 Suspense 将子组件渲染为 loading ,等到异步请求结束,loading结束,此时又回到了正常的组件。
翻了一下 unstable_createResource
的源码,果然 Pending
状态下会 throw
一个 suspender
对象,这个对象就是一个 promise
。
function unstable_createResource(fetch, maybeHashInput) { // ... var resource = { read: function (input) { // ... var key = hashInput(input); var result = accessResult(resource, fetch, input, key); switch (result.status) { case Pending: { var suspender = result.value; throw suspender; } case Resolved: { var _value = result.value; return _value; } case Rejected: { var error = result.value; throw error; } default: // Should be unreachable return undefined; } }, // ... }; return resource; } 复制代码
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Servlet与JSP核心编程
(美国)霍尔等著、赵学良译 / 霍尔 / 清华大学出版社 / 2004-06-01 / 59.0
《Servlet与JSP核心编程》(第2版)叙述详尽,条理清晰。对于初学者来说是一本不可多得的入门书籍,经验丰富的Servelet和JSP开发人员也可以通过阅读《Servlet与JSP核心编程》(第2版)得到巩固和提高。一起来看看 《Servlet与JSP核心编程》 这本书的介绍吧!