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

React类组件中调用异步天气API函数出现两次重复调用问题

重复调用的根本原因

  • 第一个原因是你把请求触发逻辑直接写在了WeatherCard函数组件的顶层:函数组件的顶层代码会在每一次组件渲染时全量执行,不管是父组件重渲染、props变化、state更新都会触发调用,本身逻辑就存在重复执行的风险。
  • 第二个原因是React 18+开发环境默认开启的严格模式(StrictMode):为了帮开发者检测未正确清理的副作用,严格模式下会故意执行两次组件挂载逻辑,刚好触发了你顶层的请求函数执行两次,生产环境不会有这个表现,但本质上还是你代码的副作用位置不对导致的。

修复方案

首先把WeatherCard里的请求调用移到useEffect副作用钩子中,指定稳定依赖即可保证只在组件挂载时执行一次:

import { useEffect } from 'react';

const WeatherCard = ({ getResults }) => {
  // 仅组件挂载时执行一次
  useEffect(() => {
    getResults();
  }, [getResults]);
  return <div></div>;
};

你当前的类组件中getResults用箭头函数定义,引用本身是稳定的,不需要额外处理;如果后续转成函数组件,可以搭配useCallback包裹getResults避免函数引用变化触发额外执行。
如果需要避免开发环境严格模式下的重复请求,可以给请求加取消逻辑:

// 修改submitQuery接收abort信号
async function submitQuery(props, signal) {
  const submission = {
    zip: props,
  };

  if (!Number(props)) return console.log("this is not a number");

  const { error } = await validate(submission);
  if (error) return console.log(error.message);

  const config = {
    method: "get",
    url: `https://api.openweathermap.org/data/2.5/weather?zip=${props}&appid=${apiKey}`,
    headers: {},
    signal // 传入abort信号
  };
  // 后续请求逻辑保持不变
}

// WeatherCard内的useEffect加清理逻辑
useEffect(() => {
  const controller = new AbortController();
  getResults(controller.signal);
  // 组件卸载/副作用重新执行前取消请求
  return () => controller.abort();
}, [getResults])

内容的提问来源于stack exchange,提问作者genus20

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 09:45:03