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

使用自定义fetch hook的React组件为何在请求报错后被卸载?

问题根因

你观察到的hook清理函数触发不是组件卸载导致的,是useFetch内部useEffect的依赖项变化触发的上一轮effect清理,具体问题出在两个点:

  • 每次点击提交按钮调用setPostData时,传入的options都是全新的对象引用,导致useEffect的依赖项[url, options]发生变化,会先执行上一轮effect的清理函数,将cancelRequest.current设置为true
  • 新的effect回调执行时,没有重置cancelRequest.current的状态,fetchData第一行判断cancelRequest.current为真,直接终止了请求逻辑,所以看起来无法重新发起请求

修复方案

1. 快速修复当前问题

在useFetch.ts的useEffect回调开头新增重置取消状态的逻辑即可:

useEffect(() => {
  // 新增这行,每次新请求发起前重置取消标记
  cancelRequest.current = false
  if (!url) return

  const fetchData = async () => {
    // 原有逻辑保持不变
  }

  fetchData()

  return () => {
    cancelRequest.current = true
  }
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [url, options])

2. 优化建议

  • 你的useFetch当前是自动触发请求的设计,更适合页面加载时拉取GET接口的场景,提交类场景建议调整useFetch的设计,返回一个手动触发的run方法,不用通过修改state变更依赖项来触发请求,逻辑会更清晰
  • 登录是POST请求,不要使用缓存逻辑,建议给hook新增enableCache配置项,POST请求默认关闭缓存,避免后续出现提交后拿旧缓存的问题
  • options是引用类型,直接放在依赖项里会导致不必要的effect触发,建议用深比较依赖的useEffect,或者将options序列化后作为依赖项

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 11:06:04