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

切换国家状态调用OpenWeatherMap API获取天气时出现TypeError错误的技术求助

解决React中切换国家时天气数据访问的TypeError问题

这个问题很常见,根源在于你的组件在初始渲染或者切换国家后,axios请求还没返回数据时,weather对象的main属性还不存在,导致访问weather.main.temp时抛出Uncaught TypeError: Cannot read properties of undefined (reading 'temp')错误。下面给你几种实用的解决办法:

1. 使用可选链操作符(最简洁)

ES2020引入的可选链操作符?.可以在访问嵌套属性时自动处理undefined/null的情况,如果链上的某个属性不存在,会直接返回undefined而不报错。修改你的温度渲染代码即可:

const WeatherInfo = ({ country }) => { 
  const [weather, setWeather] = useState({}); 
  useEffect(() => { 
    axios 
      .get(`https://api.openweathermap.org/data/2.5/weather?q=${country.capital}&appid=${api_key}&units=imperial`) 
      .then(response => { 
        console.log(response.data) 
        setWeather(response.data) 
      }) 
  }, [country]) 
  return ( 
    <div> 
      <h3>Weather in {country.capital}</h3> 
      <p><b>Temperature</b>: {weather.main?.temp} °F</p> 
    </div> 
  ) 
}

2. 条件渲染(更直观)

通过检查weather.main是否存在,再决定是否渲染温度相关内容,避免在数据未就绪时访问不存在的属性:

const WeatherInfo = ({ country }) => { 
  const [weather, setWeather] = useState({}); 
  useEffect(() => { 
    axios 
      .get(`https://api.openweathermap.org/data/2.5/weather?q=${country.capital}&appid=${api_key}&units=imperial`) 
      .then(response => { 
        console.log(response.data) 
        setWeather(response.data) 
      }) 
  }, [country]) 
  return ( 
    <div> 
      <h3>Weather in {country.capital}</h3> 
      {/* 只有当weather.main存在时才渲染温度 */}
      {weather.main && (
        <p><b>Temperature</b>: {weather.main.temp} °F</p>
      )}
    </div> 
  ) 
}

3. 初始化state时设置默认结构

你可以在初始化weather状态时,给它一个和API返回结构一致的默认值,这样初始渲染时就不会出现属性不存在的情况:

const WeatherInfo = ({ country }) => { 
  // 初始化时给main和temp一个默认值
  const [weather, setWeather] = useState({ main: { temp: 'Loading...' } }); 
  useEffect(() => { 
    axios 
      .get(`https://api.openweathermap.org/data/2.5/weather?q=${country.capital}&appid=${api_key}&units=imperial`) 
      .then(response => { 
        console.log(response.data) 
        setWeather(response.data) 
      }) 
  }, [country]) 
  return ( 
    <div> 
      <h3>Weather in {country.capital}</h3> 
      <p><b>Temperature</b>: {weather.main.temp} °F</p> 
    </div> 
  ) 
}

进阶:添加加载和错误处理(提升用户体验)

为了让用户更清楚当前状态,你可以添加加载状态和错误处理,避免数据未返回时页面显示空白或奇怪的内容:

const WeatherInfo = ({ country }) => { 
  const [weather, setWeather] = useState({}); 
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);

  useEffect(() => { 
    // 切换国家时重置状态
    setLoading(true);
    setError(null);
    axios 
      .get(`https://api.openweathermap.org/data/2.5/weather?q=${country.capital}&appid=${api_key}&units=imperial`) 
      .then(response => { 
        console.log(response.data) 
        setWeather(response.data) 
      })
      .catch(err => {
        setError('Failed to fetch weather data');
        console.error('Weather fetch error:', err);
      })
      .finally(() => {
        setLoading(false);
      })
  }, [country]) 

  // 加载中状态
  if (loading) return <div>Loading weather data for {country.capital}...</div>;
  // 错误状态
  if (error) return <div className="error">{error}</div>;

  return ( 
    <div> 
      <h3>Weather in {country.capital}</h3> 
      <p><b>Temperature</b>: {weather.main?.temp} °F</p> 
    </div> 
  ) 
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 06:51:01