【问题标题】:I cannot make a good API call我无法进行良好的 API 调用
【发布时间】:2022-08-17 16:15:26
【问题描述】:

我正在开发一个天气应用程序项目。我的问题是,当我尝试使用该 API 中的 map 方法访问 list 属性时,出现错误:

react-refresh-runtime.development.js:315 Uncaught TypeError: Cannot read properties of undefined (reading \'map\')

我认为问题在于返回方法是在未调用 API 之前执行的。因此,代码会引发此错误。我该如何解决?

Api 调用组件:

function ApiCall({ getSelection }) {
  const [takeData, setTakeData] = useState({})
  const [loading, setLoading] = useState(false)

  useEffect(() => {
    const fetchApi = async () => {
      try {
        const res = await axios(`https://api.openweathermap.org/data/2.5/forecast?q=${getSelection}&appid=\"Here is the API key\" `)
        setTakeData(res.data)
        console.log(res.data)
      } catch (err) {
        console.error(err)
      }
      setLoading(false)
    }
    fetchApi()
  }, [getSelection])

  if (loading===true) {
    return <div>Loading...</div>
  }
  
  const { city, list } = takeData
  // console.log(\"IS UPDATED: \",city?.name)
  
  return (
    <div>
      {
        // use map method since it is a list
        list.map(el => el[0].main.temp)
      }
    </div>
  )
}

这是来自 API 的数据

list: Array(40)
0:
clouds: {all: 0}
dt: 1660726800
dt_txt: \"2022-08-17 09:00:00\"
main: {temp: 299.42, feels_like: 299.42, temp_min: 299.42, temp_max: 301.99, pressure: 1006, …}
pop: 0
sys: {pod: \'d\'}
visibility: 10000
weather: [{…}]
wind: {speed: 2.31, deg: 292, gust: 3.03}
[[Prototype]]: Object
1: {dt: 1660737600, main: {…}, weather: Array(1), clouds: {…}, wind: {…}, …}
2: {dt: 1660748400, main: {…}, weather: Array(1), clouds: {…}, wind: {…}, …}

    标签: javascript reactjs


    【解决方案1】:

    这是因为在获取完成之前调用了list.map()。要修复它,当在其上调用 map() 函数时,您需要确保 list 是一个数组。一种方法是设置一个默认的空数组,如下所示:

    const [takeData, setTakeData] = useState({list: []})
    

    【讨论】:

      【解决方案2】:

      问题是组件的渲染方法在您为其赋值之前尝试使用list 状态,这就是您收到undefined 错误的原因。

      在使用它之前尝试检查列表值,如下所示:

      return (
          <div>
            {
              if (list) {
                 // use map method since it is a list
                 list.map(el => el[0].main.temp)
              }
              else {
                 Loading...
              }
            }
          </div>
        )
      

      【讨论】:

        【解决方案3】:

        在调用 api 之前,您应该 setLoading true 来渲染 Loading... html

        function ApiCall({ getSelection }) {
          const [takeData, setTakeData] = useState({})
          const [loading, setLoading] = useState(false)
        
          useEffect(() => {
            const fetchApi = async () => {
            setLoading(true); // before api call you should setLoading true for render <div>Loading...</div> html
              try {
                const res = await axios(`https://api.openweathermap.org/data/2.5/forecast?q=${getSelection}&appid="Here is the API key" `)
                setTakeData(res.data)
                console.log(res.data)
              } catch (err) {
                console.error(err)
              }
              setLoading(false)
            }
            fetchApi()
          }, [getSelection])
        
          if (loading===true) {
            return <div>Loading...</div>
          }
          
          const { city, list } = takeData
          // console.log("IS UPDATED: ",city?.name)
          
          return (
            <div>
              {
                // use map method since it is a list
                list?.map(el => el[0].main.temp) // <=== also use optional chaining
              }
            </div>
          )
        
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-08-27
          • 2021-02-08
          • 2014-09-17
          • 1970-01-01
          • 2019-01-27
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多