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

