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
相关产品推荐
相关产品推荐

