suspense组件使用时,遇到的疑点

来源:3-22 实践 Suspense

慕妹8262677

2023-03-16

1:在调用FetchData这个方法返回的方法的时候,如果把它放进useEffect,会因为最开始状态是pending而报错,报错内容:uncatch:promise
2.在调用FetchData这个方法返回的方法的时候,如果就直接放在组件里面,但不是在useEffect里面调用,则不会因为状态最开始是pendding而报错,其次
在wrapPromise方法里面,result获取值是在then里面这个微任务获取的,之后我们就直接在组件里面去调用了const imageInfo = ImageData.read(),为什么状态成功后,会更新到read里面,我的理解是调用read 的时候应该是执行同步的任务才对,此时result应该是拿不到这个返回成功的值的
这是fetchData.ts:

import axios from "axios";
function wrapPromise(promise: Promise<any>) {
    let status = "pending";
    let result: any;
    const suspendor = promise.then((res) => {
        console.log('promise===>',res)
        status = "success"
        result = res
    }, (err) => {
        console.log('promise===>',err)
        status = "error"
        result = err
    })
    
    return {
        read(){
            if(status==="success"){
                console.log('success')
                return result
            }else if(status==="error"){
                console.log('error')
                throw result
            }else if(status==="pending"){
                console.log('pending')
                throw suspendor
            }
        }
    }
}

export function fetchData(url:string){
    let promise = axios.get(url).then(res=>{
        console.log(res.data)
        return res.data
    })
    return wrapPromise(promise)
}

这是用到fetchData的组件:

import React,{useEffect,useState} from "react";
import {fetchData} from '@/utils/fetchData'
let ImageData = fetchData("https://dog.ceo/api/breeds/image/random")
const ImageShow:React.FC=()=>{
    const [imgsrc,setImgsrc] = useState('')
    const imageInfo = ImageData.read()
        console.log(imageInfo)
    
    return (
        <div>
            <img src={imageInfo.message}/>
        </div>
    )
}

export default ImageShow

还请老师麻烦解答下我的疑惑

写回答

2回答

张轩

2023-03-19

同学你好

我刚查阅了 react 最新发布的文档,其中suspense 章节的内容更多了。

https://react.dev/reference/react/Suspense

你往下滑一些,可以看到一个 Note,是这样描述的:

Only Suspense-enabled data sources will activate the Suspense component. They include:
    Data fetching with Suspense-enabled frameworks like Relay and Next.js
    Lazy-loading component code with lazy
Suspense does not detect when data is fetched inside an Effect or event handler.

Suspense 现在不支持在 Effect 中获取,所以你的这种写法是不被支持的。

并且它还说到 suspense 最好是和 Relay 和 Next.js 这样的框架一起使用,它们才支持 Suspense-enabled 的 data,怎样创建一个 Suspense 支持的数据源,也没有过多的书写,并且说以后还会发生变化。

我这种写法是之前在 Relay 和一些教程中总结的,这里只要了解就好,Suspense 本身也是一个实验特性,最好是配合框架一起使用。

0
1
慕妹8262677
好的,谢谢老师
2023-03-20
共1条回复

张轩

2023-03-17

同学你好

能否提供一下你的代码库(git)?在 useEffect 中的调用的方式? 我用代码帮你在本地看一下。

谢谢

0
4
慕妹8262677
回复
张轩
老师您好!https://git.imooc.com/Potato-X/react-with-ts 这是我新创的一个公开的git仓库,还麻烦您帮我看下我说的那个地方呢
2023-03-18
共4条回复

React18+TS高仿AntD从零到一打造组件库

设计,开发,测试,发布再到 CI/CD,从0到1造轮子

2123 学习 · 959 问题

查看课程