React18: 如何使用Suspense 等待数据异步加载

Suspense API

在这里插入图片描述
Suspense 主要有两大用途:
1:动态加载组件 (但这并不是一个react 18的新特性)
2: 等待数据异步加载

想要实现这两种功能,需要满足对应的条件,可以在官方文档中清楚的看到:

在这里插入图片描述
从文档中可以看到只有Suspense-enabled data sources才可以使用这个标签,
那么在Data fetching ,也就是等待数据异步加载的过程中,则需要对数据进行特殊的处理,现有的Relay框架,Next框架则已经支持这种格式,可以直接使用Suspense,这也是suspense 处于一个实验性阶段的原因之一,希望越来越多的框架可以支持suspense~。

将Promise 转化为 Suspense支持的数据机构

既然要使用suspense ,那么就要把数据转化为suspense支持的格式,具体我们可以通过实现一个 wrapPromise 函数来进行处理:

这个函数需要完成:

  1. 接收一个Promise 作为参数
  2. 当 promise resolve 时,返回resolve 的结果
  3. 当promise reject时, 抛出 reject 的结果
  4. 当promise 还处于pending时,抛出此时的promise对象
  5. 向外暴露一个read 方法,读取promise 的结果

接下来使用代码来实现:



function wrapPromise (promise: Promise<any>) {
     let status = 'pending';
     let result: any;

     const suspender = promise.then( (resolve) => {
        status = 'success';
        result = resolve;
     }, (err) => {
        status = 'error';
        result = err
     }) 

     return {
        read(){ // 暴露一个read方法
            if( status === 'pending'){
                throw suspender
            } else if ( status === 'error'){
                throw result
            } else if ( status === 'success'){
                return result
            }
        }
     }
}

有了这个函数之后,就可以对得到的promise对象进行处理

for example:

export default function fetchData(url: string){
    const promiseData = axios.get(url).then( data => data.data)
    return wrapPromise(promiseData)
}

请求数据并展示在页面中

// DogShow.tsx

import React from "react"
import fetchData from "../fetchData/fetchData"

const data = fetchData('https://dog.ceo/api/breeds/image/random')

const ShowDog: React.FC = () => {
    const style = {
        height: 300,
        width : 300
    }
    const dogData = data.read()
    return (
        <> 
            <img src={dogData.message} style={style}/>
        </>
    )
}

export default ShowDog
// App.tsx

function App() {
  
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <Suspense fallback={<><h1>正在加载....</h1></>}>
             <ShowDog></ShowDog>
        </Suspense>
      </header>
    </div>
  );
}

export default App;

Suspense 强制接收一个 fallback,这里面可以是发送请求时要加载的组件

数据正在请求时:
在这里插入图片描述
请求完成之后则会替换成相应的结果
在这里插入图片描述
以上,
文中如果有任何问题欢迎大家交流与讨论~

有关suspense 其他内容可以查阅官方文档:

https://react.docschina.org/reference/react/Suspense

  • 9
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值