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

React中useEffect内async函数致API两次调用的原因及解决需求

API调用两次的原因及解决办法

为什么会调用两次?

  • 依赖触发重复执行:你的useEffect依赖了dataFetched状态。初始dataFetched是false,第一次useEffect执行时,因为!dataFetched为true,会调用fetchData(),紧接着同步执行setDataFetched(true)。状态更新后组件重新渲染,useEffect因为依赖的dataFetched变化,会再次执行。再加上*React严格模式(开发环境默认开启)*会刻意重复调用useEffect来检测潜在bug,这就导致第一次的useEffect被执行两次,进而触发两次API请求。
  • 异步逻辑顺序问题:你在调用异步的fetchData()后立刻同步更新dataFetched,这时候请求还没完成,但状态已经变了,结合严格模式的重复执行机制,就容易出现两次请求。

实现仅调用一次的方法

方法一:移除dataFetched状态,用空依赖数组

这是最简洁的方式,让useEffect只在组件挂载时执行一次,不需要额外状态控制:

React.useEffect(() => {
    async function fetchData() {
        // 修正URL缺失的?,否则请求会失败
        const response = await fetch(
            "https://opentdb.com/api.php?amount=5&category=31&difficulty=easy&type=multiple"
        );
        const jsonData = await response.json();
        setData(jsonData.results);
    }
    fetchData();
}, []); // 空依赖数组,仅组件挂载时执行一次

方法二:保留dataFetched但调整逻辑

如果一定要用dataFetched状态,把setDataFetched(true)放到异步函数内部,确保请求完成后再更新状态,避免同步更新带来的重复触发:

React.useEffect(() => {
    async function fetchData() {
        const response = await fetch(
            "https://opentdb.com/api.php?amount=5&category=31&difficulty=easy&type=multiple"
        );
        const jsonData = await response.json();
        setData(jsonData.results);
        setDataFetched(true); // 请求完成后再标记已获取数据
    }

    if (!dataFetched) {
        fetchData();
    }
}, [dataFetched]);

内容的提问来源于stack exchange,提问作者Shin Thant Maung

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 11:02:51