循环调用自定义REST API时数据被覆盖,如何获取各链接独立数据?
解决循环调用API时数据被覆盖的问题
问题根源
你在循环中调用useFetch的写法违反了React Hook的核心规则:Hook必须在组件的顶层作用域调用,不能在循环、条件判断或嵌套函数内执行。这种写法会导致Hook的调用顺序混乱,最终出现状态被最后一次请求覆盖的问题。
解决方案
方案1:使用useEffect结合Promise.all批量请求
直接在组件顶层通过useEffect批量发起所有请求,统一处理结果:
import { useState, useEffect } from 'react'; function WeatherComponent() { const [weatherData, setWeatherData] = useState([]); const arrayOfUrls = [ "http://localhost:8080/weatherapi/mechelen", "http://localhost:8080/weatherapi/denbosch", "http://localhost:8080/weatherapi/antwerp" ]; useEffect(() => { const fetchAllWeather = async () => { // 为每个URL创建请求Promise const requestPromises = arrayOfUrls.map(url => fetch(url).then(response => response.json()) ); // 等待所有请求完成 const results = await Promise.all(requestPromises); // 将结果与对应城市关联,避免混淆 const formattedData = arrayOfUrls.map((url, index) => ({ city: url.split('/').pop(), weather: results[index] })); setWeatherData(formattedData); }; fetchAllWeather(); }, []); return ( <div> {weatherData.map(item => ( <div key={item.city}> <h3>{item.city}</h3> <pre>{JSON.stringify(item.weather, null, 2)}</pre> </div> ))} </div> ); }
方案2:拆分到独立子组件调用Hook
把单个城市的请求逻辑拆分到子组件中,每个子组件在顶层调用useFetch,保证每个请求的状态独立:
// 子组件:负责单个城市的天气请求与展示 import { useFetch } from './your-useFetch-module'; function WeatherCard({ cityUrl }) { const { data: weather } = useFetch(cityUrl); const cityName = cityUrl.split('/').pop(); if (!weather) return <div>加载中...</div>; return ( <div> <h3>{cityName}</h3> <pre>{JSON.stringify(weather, null, 2)}</pre> </div> ); } // 父组件:渲染所有城市的WeatherCard function WeatherComponent() { const arrayOfUrls = [ "http://localhost:8080/weatherapi/mechelen", "http://localhost:8080/weatherapi/denbosch", "http://localhost:8080/weatherapi/antwerp" ]; return ( <div> {arrayOfUrls.map(url => ( <WeatherCard key={url} cityUrl={url} /> ))} </div> ); }
说明
- 方案1适合需要统一处理所有请求结果的场景,一次性获取所有数据,避免多次状态更新。
- 方案2更符合React组件拆分的思想,每个子组件独立管理自己的请求状态,完全遵循Hook调用规则,不会出现数据覆盖问题。
内容的提问来源于stack exchange,提问作者Mathias Van Langendonck
相关产品推荐
相关产品推荐

