React组件中调用外部封装的fetch函数获取天气数据并更新状态的方法
解决方案
核心原因
你抽离后的fetchCityData工具函数不持有ForecastButtons组件内部的状态更新方法setPayload,也不会自动将返回值注入组件状态,因此需要你在组件侧主动接收异步返回的天气数据,再触发状态更新。
改造步骤
步骤1:调整fetchCityData为纯请求工具函数
确保工具函数只负责请求逻辑,直接返回包含天气数据的Promise,不要耦合组件状态逻辑:
// lib/cityData.js export async function fetchCityData(city) { try { const response = await fetch(`你的天气接口请求地址?city=${encodeURIComponent(city)}`) if (!response.ok) throw new Error('天气接口请求失败') return await response.json() // 直接返回接口的天气对象 } catch (error) { console.error('获取城市天气数据失败:', error) throw error // 将错误抛出给组件侧处理 } }
步骤2:组件内处理异步返回结果更新状态
在ForecastButtons组件的点击事件中,通过async/await拿到工具函数返回的天气数据后,主动调用setPayload更新组件状态:
// ForecastButtons.jsx import { useState } from 'react' import { fetchCityData } from '@/lib/cityData' export default function ForecastButtons({ city }) { const [payload, setPayload] = useState(null) const [loading, setLoading] = useState(false) // 按钮点击事件 const handleGetWeather = async () => { if (!city) return setLoading(true) try { // 主动接收工具函数返回的天气数据 const weatherData = await fetchCityData(city) // 调用组件内部方法更新状态 setPayload(weatherData) } catch (err) { // 可自定义错误提示逻辑 console.error('加载天气数据失败', err) } finally { setLoading(false) } } return ( <div> <button onClick={handleGetWeather} disabled={loading}> {loading ? '加载中' : '获取选中城市天气'} </button> {/* 展示当前温度 */} {payload && <p>当前温度:{payload.temperature}℃</p>} </div> ) }
可选方案:将状态更新方法作为参数传入(不推荐)
如果需要将状态更新逻辑也封装到工具函数中,可以把setPayload作为参数传入fetchCityData,该方案会导致工具函数和React组件逻辑耦合,仅适合单项目复用的场景:
// lib/cityData.js 调整后 export async function fetchCityData(city, setPayload) { try { const response = await fetch(`你的天气接口请求地址?city=${encodeURIComponent(city)}`) const weatherData = await response.json() setPayload(weatherData) } catch (error) { console.error(error) } } // 组件内调用 const handleClick = () => { fetchCityData(city, setPayload) }
注意事项
- 必须添加
async/await或.then()处理异步返回逻辑,否则直接拿到的是Pending状态的Promise,无法获取实际天气数据 - 建议添加loading状态和错误兜底逻辑,避免接口异常时页面无响应
- 跨框架/多项目复用工具函数时优先选择第一种方案,保持工具函数的纯功能性
内容的提问来源于stack exchange,提问作者Katharina Schreiber
相关产品推荐
相关产品推荐

