React子组件调用setState后持续刷新重复请求服务器问题求助
问题原因与解决方案
你的问题出在子组件的useEffect没有设置依赖数组,且状态更新触发的重渲染会反复执行effect,形成无限循环:
- 当调用
setRepairCentres更新状态时,子组件会重新渲染 - 由于
useEffect未指定依赖项,每次重渲染都会重新执行fetch请求 - 请求完成后又更新状态,再次触发重渲染,最终导致持续刷新和频繁请求服务器
修复后的子组件代码
export function RepairCentreResults({search}: { search: string }) { const [isLoading, setIsLoading] = useState(true) const [repairCentres, setRepairCentres] = useState<RepairCentreDto[]>([]) useEffect(() => { // 每次搜索关键词变化时,重置加载状态 setIsLoading(true); // 创建AbortController处理请求取消,避免竞态问题 const controller = new AbortController(); const signal = controller.signal; fetch(`http://localhost:5193/GetRepairCentres?search=${encodeURIComponent(search)}`, { signal }) .then(res => { if (!res.ok) throw new Error('请求失败'); return res.json(); }) .then((repairCentres : RepairCentreDto[]) => { setRepairCentres(repairCentres); }) .catch(err => { // 忽略请求被主动取消的错误 if (err.name !== 'AbortError') { console.error('获取维修中心数据失败:', err); } }) .finally(() => { // 请求结束后关闭加载状态 setIsLoading(false); }); // 组件卸载或搜索关键词变化时,取消未完成的请求 return () => controller.abort(); }, [search]); // 仅当search参数变化时,才执行effect逻辑 if (isLoading) return <p>Loading...</p> return ( <div className="table-responsive"> {/* 此处添加维修中心列表的渲染逻辑 */} </div> ); }
关键改进点
- 添加依赖数组
[search]:确保只有当搜索关键词变化时,才触发新的请求,避免内部状态更新导致的重复请求 - 请求取消机制:用
AbortController处理快速输入时的竞态问题,防止旧请求返回后覆盖新的搜索结果 - 参数编码:用
encodeURIComponent处理搜索参数,避免特殊字符导致的请求错误 - 加载状态重置:每次搜索时重新开启加载状态,保证UI反馈准确
内容的提问来源于stack exchange,提问作者Bluebaron
相关产品推荐
相关产品推荐

