首页 > 解决方案 > React hooks async 问题:map 在数据返回之前执行 - 解决方案?

问题描述

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

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

所以我猜测正在发生的事情是 setState 是 aysnc,并且在gig.map设置gigfilteredGigs.

对于如何解决这个问题,有任何的建议吗?

这是完整的代码:

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

标签: reactjsaxiosreact-hooks

解决方案


问题

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

解决方案

只需将过滤后的 gig 数组保存到 state 中。这将使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
  })
},[])

推荐阅读