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

React使用map与fetch渲染天气列表时出现意外多份数据问题

天气应用数据重复渲染修复方案

核心故障原因

  • 子组件DisplayWeather的useEffect逻辑错误:每次传入的城市列表更新时,你遍历了所有城市重新发起请求,且每个请求返回后都向已有结果数组追加数据,没有清空上一次的缓存,是重复渲染的直接原因。比如初始传入「伦敦」,请求后数组存了1条伦敦;新增「柏林」后遍历「伦敦、柏林」两个城市重新请求,伦敦请求先返回,追加后数组变成「伦敦、伦敦」,柏林请求返回后再追加,最终就是「伦敦、伦敦、柏林」,完全匹配你遇到的现象。同时你直接在map中执行异步函数没有做聚合,请求返回顺序不可控,还可能出现展示顺序和城市顺序不一致的问题。
  • 父组件App的状态更新写法存在闭包隐患:addCity和loadCityFromLocalStore中直接用当前闭包中的cities做展开更新,高频率操作时可能出现状态丢失。

修复后代码

App(父组件)

const App = () => {
  const [cities, setCities] = useState([]);

  const addCity = (newCity)=>{
    console.log('adding')
    // 改用函数式更新取最新状态,避免闭包问题
    setCities(prev => [...prev, newCity]);
    const cityId = localStorage.length;
    localStorage.setItem(`city${cityId}`, newCity);
  }

  useEffect(() => {
    loadCityFromLocalStore()
  }, [])

  const loadCityFromLocalStore =()=>{   
    // 改用函数式更新,不依赖初始空状态
    setCities(prev => [...prev, ...Object.values(localStorage)])
  }

  return (
    <div>
      <Header />
      <AddCity addCity={addCity}/>
      <DisplayWeather displayWeather={cities}/>
    </div>
  )
}

DisplayWeather(第一层子组件)

const DisplayWeather = ({displayWeather}) => {
  const apiKey = '4c97ef52cb86a6fa1cff027ac4a37671';
  const [fetchData, setFetchData] = useState([]);

  useEffect(() => {
    // 空列表跳过请求
    if(displayWeather.length === 0) return;
    // 用Promise.all批量处理请求,保证返回顺序和城市顺序一致
    const fetchAllCities = async () => {
      const requests = displayWeather.map(async city => {
        const res = await fetch(`http://api.openweathermap.org/data/2.5/weather?q=${city}&units=metric&appid=${apiKey}`)
        return res.json();
      })
      const allData = await Promise.all(requests);
      // 直接替换整个结果数组,不追加,彻底避免重复
      setFetchData(allData);
    }
    fetchAllCities();
  }, [displayWeather])

  return (
    <>
      {/* 新增唯一key,避免React列表渲染警告 */}
      {fetchData.map(data=>(            
        <ul key={data.id}>
          <Weather data={data}/> 
        </ul>
      ))}
    </>
  )
}

Weather组件

保持原有逻辑即可,建议给li元素也加上唯一key优化渲染性能。

内容的提问来源于stack exchange,提问作者Seweryn Woźniak

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 04:21:03