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

React中调用封装的fetchQuery请求GraphQL接口触发两次如何解决?

问题根因
  • 你直接把fetchQuery调用放在了函数组件的顶层,没有做执行限制,组件每次重新渲染都会重新执行一次这个请求。
  • 若你使用的是React 18及以上版本,开发环境下默认开启的严格模式(<StrictMode>)会让组件执行两次挂载流程,用于排查副作用未正确清理的问题,这也会额外触发一次请求。

另外你在请求回调里直接操作原生DOM追加标签的写法不符合React的渲染逻辑,后续组件重渲染时会出现标签重复追加的问题,建议用React状态管理渲染内容。

修复方案

调整NavBar组件的代码,用useEffect包裹请求逻辑限制执行时机,用useState存储返回的分类数据做声明式渲染:

import React, { useEffect, useState } from 'react'
import '../App.css';
import {fetchQuery} from '../fetching'

function NavBar() {
    // 定义存储分类数据的状态
    const [categories, setCategories] = useState([])

    useEffect(() => {
        // 请求逻辑放在useEffect里,空依赖数组代表仅在组件首次挂载后执行一次
        fetchQuery(`
            query{
                categories{
                name
                }
            }
        `).then(data => {
            setCategories(data.data.categories)
        })
    }, []) // 空依赖数组是关键,确保只执行一次

    return (
        <div className = "NavBar">
            <div className = "leftSide" id = "leftNav">
                <div className = "links" id="leftNavElements" >
                    <a href = "/">ALL</a>
                    {/* 直接遍历状态渲染标签 */}
                    {categories.map(item => (
                        <a href={`/${item.name}`} key={item.name}>{item.name}</a>
                    ))}
                </div> 
            </div>
            <div className = "centerSide">
                Logo
            </div>
            <div className = "rightSide">
                Cart & Currency Change
            </div>
        </div>
    );
}

export default NavBar;

修改后生产环境下请求只会执行一次,开发环境下如果还是看到两次打印,是严格模式的正常表现,打包部署到生产环境后就会自动消失,不影响功能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 09:36:01