React自定义useFetchQL Hook重复请求问题:单次查询触发700+次调用求助
问题原因与解决方案
问题原因
- 自定义Hook未控制请求执行时机:
useFetchQL直接在Hook顶层调用getData(),每次组件渲染(包括初始渲染、状态更新触发的重渲染)都会执行该函数发起新请求。而setData更新状态又会触发组件重渲染,形成循环,导致大量重复请求。 - App组件错误使用Hook返回值:用
setChars(useFetchQL(...))的写法完全违规,setChars会触发App组件重渲染,重渲染又会再次调用useFetchQL,进一步加剧重复请求问题,同时不符合React Hook的使用规范。
解决步骤
- 在
useFetchQL中用useEffect包裹请求逻辑,设置空依赖数组,确保请求仅在Hook挂载时执行一次。 - 修正App组件用法:直接接收
useFetchQL返回的状态,无需额外维护chars状态。 - 修正参数类型不匹配问题:原Hook参数定义为
URL类型,调用时传入的是字符串,调整参数类型为string避免类型报错。
修改后的代码
自定义Hook useFetchQL.ts
import { useState, useEffect } from 'react'; export const useFetchQL = (url: string): Array<Object> => { const [data, setData] = useState([]); const getData = async () => { const query = ` query { characters{ id name title imageURL leaderSkill passive categories links } }`; try { const response = await fetch(url, { method: "POST", headers: { "Content-Type": "application/json", "Accept": "application/json" }, body: JSON.stringify({ query }), }); const result = await response.json(); setData(result.data.characters); } catch (error) { console.error("请求出错:", error); } }; // 仅在组件挂载时执行一次请求 useEffect(() => { getData(); }, []); return data; };
App组件
import './App.css'; import Cards from './components/Cards'; import Team from './components/Team'; import Search from './components/Search'; import { AddToTeamProvider } from './context/addToTeamContext'; import { useFetchQL } from './hooks/useFetchQL'; function App() { const chars = useFetchQL('https://dokkanapi.azurewebsites.net/graphql'); console.log(chars); return ( <div className="App"> <AddToTeamProvider> <Team /> <Search /> <Cards chars={chars} /> {/* 若Cards组件需要数据,需传递该props */} </AddToTeamProvider> </div> ); } export default App;
额外说明
- 新增
try/catch捕获请求异常,避免请求失败导致页面崩溃。 - 若后续需要根据特定条件重新发起请求,只需在
useEffect的依赖数组中添加对应变量(比如查询参数变化时重新请求)。
内容的提问来源于stack exchange,提问作者Eiron
相关产品推荐
相关产品推荐

