You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中.map()遍历的item返回undefined问题排查求助

问题:Forecast组件中map遍历数组时item返回undefined导致渲染崩溃

问题描述

在<Forecast />组件中遍历对象数组items,map()方法中的item返回undefined。虽然通过console.log能看到数据存在,但渲染item.temp等属性时程序崩溃,提示undefined。

相关代码

Forecast组件

import React from "react"

export default function Forecast({ items, title }) {
    console.log(items)
    return (
        <div>
            <div className="text-white mx-8 mt-4">
                <div className="border-b">
                    <h1 className="text-xl mb-2">{title}</h1>
                </div>
                {
                    items.map((item, i) => {
                        console.log(item)
                        return (
                            <div key={i} className="flex justify-between my-6">
                                <div className="flex flex-col items-center">
                                    <span>{item.time}</span>
                                    <span>
                                        <img src={`https://cdn.weatherbit.io/static/img/icons/${item.icon}.png`} alt="" />
                                    </span>
                                    <span>{item.temp}</span>
                                </div>
                            </div>
                        )
                    })
                }
            </div>
        </div>
    )
}

WeatherCard组件

import DefaultCitiesLI from "./DefaultCities"
import Inputs from "./Inputs"
import TimeAndLocation from "./TimeAndLocation"
import TempDetails from "./TempDetails"
import Forecast from "./Forecast"
import { useEffect, useState } from "react"
import { getCurrentData, getDailyData, getHourlyData } from "../api/weatherAPI"


export default function WeatherCard() {
    const [data, setData] = useState({})
    const [hourlyData, setHourlyData] = useState({})
    const [dailyData, setDailyData] = useState([])
    const [inputData, setInputData] = useState([])

    useEffect(() => {
        async function getData() {
            try {
                const currentHourlyData = await getHourlyData(inputData)
                const currentDailyData = await getDailyData(inputData)
                const currentWeatherData = await getCurrentData(inputData)
                setData({ current: currentWeatherData })
                setHourlyData(currentHourlyData)
                setDailyData(currentDailyData)
            } catch (err) {
                console.error("Error: " + err)
                return null
            }
        }
        getData()
    }, [inputData])

    console.log(dailyData)


    return (
        <div className="flex justify-center items-center mt-8">
            <div className="bg-[#1d2d44] rounded w-[600px] px-12 pt-12">
                <ul className="flex justify-center space-x-5">
                    <DefaultCitiesLI setInputData={setInputData} />
                </ul>
                <Inputs setInputData={setInputData} />
                {data.current &&
                    <div>
                        <TimeAndLocation weatherData={data.current} />
                        <TempDetails weatherData={data.current} />
                        <Forecast items={hourlyData} title="Hourly Forecast" />
                        <Forecast items={dailyData} title="Daily Forecast" />
                    </div>
                }
            </div>
        </div>
    )
}

解决方案

1. 检查接口返回的属性结构

最可能的原因是你假设的属性名(item.temp、item.time、item.icon)与接口实际返回的结构不匹配,比如温度嵌套在main.temp、时间字段是dt_txt、图标在weather[0].icon路径下。

操作步骤:
在Forecast的map函数中打印完整的item对象,确认实际属性路径:

items.map((item, i) => {
  console.log("完整item结构:", item);
  // ... 渲染代码
})

根据实际结构修改渲染代码,例如:

<span>{item.main.temp}</span>
<span>{item.dt_txt}</span>
<img src={`https://cdn.weatherbit.io/static/img/icons/${item.weather[0].icon}.png`} alt="" />

2. 修正hourlyData的初始状态

hourlyData初始状态设为{}(对象),但Forecast需要数组来调用map方法。异步请求未完成时,若data.current已存在,hourlyData还是初始对象,会引发错误。

操作步骤:
将hourlyData的初始状态改为数组:

const [hourlyData, setHourlyData] = useState([])

同时在Forecast中添加空数组兜底渲染:

{items.length > 0 ? (
  items.map((item, i) => {
    // ... 原有渲染代码
  })
) : (
  <span className="text-white">加载中...</span>
)}

3. 提取接口返回的数组部分

从注释代码推测,接口返回的currentHourlyData可能是包含数组的对象(比如{ data: [...] }),你直接传递整个对象给Forecast,导致items是对象而非数组,遍历出的item是对象键名,无法访问属性。

操作步骤:
确认接口结构后,提取数组部分:

// 方式1:设置状态时提取
setHourlyData(currentHourlyData.data)

// 方式2:传递给Forecast时提取
<Forecast items={hourlyData.data} title="Hourly Forecast" />

4. 同步数据加载条件

setState是异步操作,可能出现data.current已更新,但hourlyData/dailyData未完成更新的情况,导致Forecast接收初始状态数据。

操作步骤:
修改条件渲染,同时判断所有依赖数据:

{data.current && hourlyData.length > 0 && dailyData.length > 0 &&
  <div>
    <TimeAndLocation weatherData={data.current} />
    <TempDetails weatherData={data.current} />
    <Forecast items={hourlyData} title="Hourly Forecast" />
    <Forecast items={dailyData} title="Daily Forecast" />
  </div>
}

内容的提问来源于stack exchange,提问作者CrveniFlash

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 13:32:02