在Next.js应用中调用WeatherAPI获取天气数据的实现疑问
解析WeatherAPI响应数据
fetch 返回的 Response 对象只是HTTP响应的外壳,必须调用 .json() 方法将其解析为JavaScript对象,才能提取localtime这类业务字段。
代码修改示例:
- 更新/data.ts的请求函数:
export async function fetchCurrentData(location: string, apiKey: string) { const response = await fetch(`https://api.weatherapi.com/v1/current.json?key=${apiKey}&q=${location}`); // 先校验响应状态,避免解析无效数据 if (!response.ok) { throw new Error(`请求失败:${response.status}`); } // 解析为JSON对象后返回 return await response.json(); }
- 在/page.js中提取数据并传递给Card组件:
import { fetchCurrentData } from './data'; import Card from './Card'; export default async function WeatherPage() { // 建议用环境变量存API密钥,禁止硬编码 const weatherData = await fetchCurrentData('Beijing', process.env.WEATHER_API_KEY); const localtime = weatherData.location.localtime; return ( <div> <Card localtime={localtime} /> </div> ); }
最佳实践建议
- 数据与UI逻辑分离:你把请求封装在/data.ts的做法是正确的,保持UI组件只负责渲染,数据请求逻辑独立,方便后续维护和复用。
- 强制错误处理:必须添加异常捕获和状态校验,避免请求失败导致页面崩溃,比如在页面组件中处理:
export default async function WeatherPage() { let weatherData; let errorMsg; try { weatherData = await fetchCurrentData('Beijing', process.env.WEATHER_API_KEY); } catch (err) { errorMsg = err.message; } if (errorMsg) return <div>加载失败:{errorMsg}</div>; if (!weatherData) return <div>加载中...</div>; const localtime = weatherData.location.localtime; return <Card localtime={localtime} />; }
- 敏感信息隔离:API密钥绝对不能硬编码到代码里,用项目环境变量(比如Next.js的
.env.local)存储,防止提交到仓库泄露。 - TypeScript类型约束:给天气数据定义接口,提升代码可读性和类型安全:
interface WeatherLocation { name: string; localtime: string; // 其他需要用到的字段 } interface CurrentWeather { temp_c: number; condition: { text: string; icon: string; }; // 其他需要用到的字段 } interface WeatherResponse { location: WeatherLocation; current: CurrentWeather; } export async function fetchCurrentData(location: string, apiKey: string): Promise<WeatherResponse> { // 原有请求逻辑 return await response.json() as WeatherResponse; }
- 请求缓存优化:实时天气不需要秒级更新,可通过
fetch的cache选项或SWR/React Query这类库添加缓存策略,减少重复请求、提升页面性能。
内容的提问来源于stack exchange,提问作者mickle0629
相关产品推荐
相关产品推荐

