React TypeScript中Axios天气API响应数据映射问题求助
问题分析与解决方案
你的代码存在两个核心问题:组件调用方式错误,以及数据类型定义不匹配,导致无法正常访问天气数据。以下是具体的修正步骤:
1. 修正数据类型与封装逻辑
天气API返回的是单个WeatherData对象,而非数组。你之前错误地将useState和axios.get的泛型定义为数组类型,这直接引发了.location不存在的类型错误。同时,应将数据获取逻辑封装为符合React规范的自定义Hook,而非组件:
修改WeatherApi.ts:
import { useState, useEffect } from 'react'; import axios from 'axios'; import { WeatherData } from './WeatherData'; // 自定义Hook必须以use开头,符合React规范 const useWeatherApi = () => { // 初始值设为null,明确类型为单个WeatherData对象或null const [weather, setWeather] = useState<WeatherData | null>(null); // 添加加载、错误状态,处理数据获取的不同阶段 const [loading, setLoading] = useState(true); const [error, setError] = useState<string | null>(null); useEffect(() => { const url = 'https://api.weatherapi.com/v1/current.json?key=d7db22f333fc4e6aaf3110311222601&q=London&aqi=no'; axios // 泛型改为单个WeatherData对象,匹配API返回格式 .get<WeatherData>(url) .then(res => { setWeather(res.data); setError(null); }) .catch(err => { console.log(err); setError('获取天气数据失败'); setWeather(null); }) .finally(() => { setLoading(false); }); }, []); // 返回数据及状态供组件使用 return { weather, loading, error }; }; export default useWeatherApi;
2. 在App组件中正确使用Hook
React组件不能像普通函数直接调用,需在组件内部调用自定义Hook,并根据状态处理渲染逻辑:
修改App.tsx:
import useWeatherApi from '../api/WeatherApi'; const Weather = () => { // 调用自定义Hook获取数据和状态 const { weather, loading, error } = useWeatherApi(); // 加载中状态 if (loading) { return <div>加载中...</div>; } // 错误状态 if (error) { return <div>{error}</div>; } // 数据存在时安全访问并渲染 return ( <div> <h1>{weather?.location.name}</h1> <p>国家:{weather?.location.country}</p> <p>当前温度:{weather?.current.temp_c}°C</p> <p>体感温度:{weather?.current.feelslike_c}°C</p> <p>天气状况:{weather?.current.condition.text}</p> <img src={weather?.current.condition.icon} alt="天气图标" /> </div> ); }; export default Weather;
关键说明
- 自定义Hook规范:将数据获取逻辑封装为
use开头的Hook,是React复用状态逻辑的标准方式,比直接调用组件更合理。 - 可选链操作符
?.:使用weather?.location.name可避免weather为null时的undefined错误,确保代码安全。 - 状态管理:新增
loading和error状态,能清晰处理数据加载的不同阶段,提升用户体验。
内容的提问来源于stack exchange,提问作者Traznix
相关产品推荐
相关产品推荐

