如何等待来自嵌套请求的 React 评估值?

Posted

技术标签:

【中文标题】如何等待来自嵌套请求的 React 评估值?【英文标题】:How to wait for evaluating values in React from nested requests? 【发布时间】:2020-11-17 08:34:00 【问题描述】:

我遇到了 React 没有等待评估值的问题。我在 useEffect 中有大约 10 个 GET 请求,然后将其置于挂钩状态:

const [data,setData]=useState()
    useEffect(async()=>
     //here axios requests
     setData('here retrieved data above');
    ,[]);

我包裹在异步函数中,但它没有帮助,我的反应代码在没有来自 axios 请求的数据的情况下开始,但在控制台我看到来自每个请求的数据,标记为“刚刚评估了下面的值”。我怎么能等待评估?据我了解,它与变异对象有关 - https://www.freecodecamp.org/news/mutating-objects-what-will-be-logged-in-the-console-ffb24e241e07/ 但是不知道怎么解决

我的代码:

const SmallGrid = (props)=>
    return <div>
            <h1>props.name</h1>
            props.elements && props.elements.map((el, idx)=>
                return <Link to=`$el.url.split("http://swapi.dev/api")[1].slice(0, -1)` className=styles.links>el.name</Link>
            )
          </div> 
;

function UniPage(match) 
    const[data, setData] = useState();
const getData = async () => 
    try 
        const firstData = await axios.get(`https://swapi.dev/api$match.url`);
        console.log(firstData.data);
        let addData = ;
        await Promise.all(
            Object.keys(firstData.data).map((key)=>
                if(Array.isArray(firstData.data[key]))
                    let tempArray = [];
                    firstData.data[key].map((url)=>
                        axios.get(url)
                        .then((data)=>
                            tempArray.push(data.data)
                        )
                    );
                    addData[key] = tempArray;
                
            )
        ).then(result=>
            console.log(addData);
            setData(Object.assign(firstData.data,addData));
        )
     catch (err ) 
        // errors
        console.log(err,"connection error")
    


useEffect(() => 
    getData()
, []);

使用此代码,我从嵌套请求中丢失了部分数据,并在控制台中获取它,如评估值。

【问题讨论】:

【参考方案1】:

很遗憾,useEffect 无法等待 Promise 解决。这是因为,在 React 中,效果挂钩期望传递给它的函数返回的值是 cleanup function。因此,将async function 交给它会导致返回的Promise 被这样解释。

一个典型的解决方法是使用Promise.prototype.then()(以下概述为策略A)。

另一个解决方案是将所有异步逻辑转移到可以等待的单独函数中(以下概述为策略 B)。这往往是首选,因为它允许有机会通过函数名称暗示正在发生的事情并导致代码更整洁。

请参阅下面的实际示例。

// State.
const [data, setData] = useState()

// Did Mount.
useEffect(() => 
  
  // Strategy A.
  axios.get('/endpoint').then(response => setData(response.data))

  // Strategy B.
  const fetchData = async () => 
    const data = await axios.get('/endpoint')
    setData(data)
  
  fetchData()

, [])

【讨论】:

我添加了根据您的建议编写的代码,但仍然缺少数据,可能是我的临时对象变异有问题?

以上是关于如何等待来自嵌套请求的 React 评估值?的主要内容,如果未能解决你的问题,请参考以下文章

React 中嵌套获取请求的问题

在发出 POST 请求之前等待来自外部 API 的数据

如何使用 Apollo 和 React Router 避免嵌套路由/查询组件的请求瀑布?

是否应该避免嵌套锁定请求?

在 React JS 中从服务器请求数据时暂停 UI

Spring Boot 嵌套动态 json 请求映射到 pojo