React挂钩异步问题:在返回数据之前执行映射-解决方案



在下面的代码中,您可以看到我正在映射axiosGET请求返回的数据。然后,我通过一个过滤器传递这些数据,并将其设置为state(在变量gig下(。

然后我想映射gig中保存的数据——唯一的问题是,当我尝试时,我会得到一个错误,比如TypeError: gig.map is not a functiongig控制台日志未定义。但是,当gig被控制台记录在useEffect方法中时,它会返回我想要的数据。

所以我猜测发生的事情是setState是aysnc,并且在gig被设置为filteredGigs之前就达到了gig.map函数。

关于如何解决这个问题,有什么建议吗?

这是完整的代码:

import React, {useState, useEffect} from 'react'
import axios from 'axios'
import { auth } from 'firebase/app'
const UniqueVenueListing = (props) => {
const [gig, setGig] = useState([])
const authUserId =  props.userDetails.uid

useEffect(()=>{
axios.get("https://us-central1-gig-fort.cloudfunctions.net/api/getGigListings")
.then(res => {
let filteredGigs = res.data
.filter(gig => {
return gig.user !== authUserId
})
setGig({gig: filteredGigs})
console.log(gig)
})
},[])
useEffect(() => {
console.log(gig)
}, [gig])
return(

<div>
{
gig.map(gigs => {
return gigs.user
})
} 
</div>
)
}
export default UniqueVenueListing

问题

您可以更改状态形状。gig状态的初始形状是一个空数组([](,但实际上是在键gig({ gig: filteredGigs }(下存储一个带有数组的对象。此外,由于状态更新是异步的,setGig之后的console.log将只记录当前状态,而不是刚刚排队的状态。

解决方案

只需将过滤后的gig数组保存到状态即可。这将使gig状态保持为一个数组,稍后返回的gig.map(...将按预期工作。

useEffect(()=>{
axios.get("https://us-central1-gig-fort.cloudfunctions.net/api/getGigListings")
.then(res => {
const filteredGigs = res.data.filter(gig => {
return gig.user !== authUserId
})
setGig(filteredGigs); // <-- store the array in state
})
},[])

最新更新