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

React项目中从对象/数组获取图标时遇undefined读取报错

解决React中"Cannot read properties of undefined (reading '0')"报错问题

问题场景

开发React天气项目时,尝试从OpenWeatherMap API返回的数据中提取图标路径,存入变量后作为props传递给子组件<Weather>,但页面触发报错:Cannot read properties of undefined (reading '0'),仅在使用<img src={props.icon} alt="cloud" />时出现,移除该标签后页面恢复正常。

报错原因

  1. 初始状态不匹配:data的初始值设为[](数组),但API返回的是单个对象,导致初始渲染时data.weather为undefined,访问data.weather[0]直接报错。
  2. 无边界判断:在组件渲染阶段直接执行data.weather[0].icon,未考虑API请求未完成、请求失败或返回数据异常的情况,此时data.weather可能不存在。
  3. 空值渲染风险:子组件中直接渲染props.showItems.name,未做空值判断,也会在数据未返回时引发报错。

解决方案

  1. 修正初始状态:将data的初始值改为空对象{},匹配API返回的数据结构。
  2. 添加空值保护:使用可选链操作符?.或条件判断,确保在data.weather存在时再访问数组元素。
  3. 优化请求逻辑:避免在search为空时发起无效请求,减少不必要的错误。
  4. 子组件空值处理:对所有从props接收的数据添加空值判断,确保安全渲染。

修改后的代码

App.js

import React, { useEffect, useState } from "react";
import Weather from "./components/Weather";
import "./App.css";

function App() {
  const [search, setSearch] = useState("");
  const [data, setData] = useState({}); // 初始值改为空对象

  useEffect(() => {
    // 仅当search不为空时发起请求
    if (!search) return;
    
    fetch(
      `https://api.openweathermap.org/data/2.5/weather?q=${search}&appid=1769e69d20183ccd0c32ac3215db1d40&units=metric`
    )
      .then((response) => response.json())
      .then((json) => setData(json))
      .catch((error) => {
        console.error(error);
        setData({}); // 请求失败时重置data
      });
  }, [search]);

  const handleInput = (event) => {
    setSearch(event.target.value);
  };

  // 使用可选链安全提取图标,不存在时返回空字符串
  let icon = data?.weather?.[0]?.icon ? `${data.weather[0].icon}.png` : "";

  return (
    <div>
      <Weather icon={icon} inputValue={handleInput} showItems={data} />
    </div>
  );
}

export default App;

Weather.js

import "./style/Weather.css";
import "@fortawesome/fontawesome-free/css/all.css";

function Weather(props) {
  return (
    <div className="container">
      <div className="weather-container">
        <input
          onChange={props.inputValue}
          type="text"
          placeholder="Enter a city name"
        />
        {/* 添加空值判断,避免渲染undefined */}
        {props.showItems.name && <p>{props.showItems.name}</p>}
        {/* 仅当icon有值时渲染img标签 */}
        {props.icon && <img src={props.icon} alt="weather icon" />}
        {props.showItems.main && <p>{props.showItems.main.temp.toFixed()}°C</p>}
      </div>
    </div>
  );
}

export default Weather;

内容的提问来源于stack exchange,提问作者Mirza Šabanović

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 12:51:05