使用自定义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
相关产品推荐
相关产品推荐

