React中useUserSearch钩子的axios.CancelToken逻辑详解
解析useUserSearch Hook中的Axios请求取消逻辑
为什么要做请求取消?
这个逻辑核心是解决请求竞态问题:
- 比如用户快速切换搜索关键词(比如从"张三"改成"李四"),或者连续点击翻页,前一次的请求还没返回,新的请求已经发出去了。如果不取消旧请求,就可能出现旧请求晚于新请求返回的情况,导致页面显示的是旧的搜索结果,把新结果覆盖掉,造成数据混乱。
- 另外,取消已经不需要的请求,还能节省网络带宽,减少服务器的无效负载。
Axios CancelToken 怎么工作?
axios.CancelToken是Axios官方提供的请求取消机制,拆解一下代码里的用法:
let cancel; axios.get(..., { cancelToken: new axios.CancelToken((c) => (cancel = c)), })
- 当创建
CancelToken实例时,Axios会传入一个回调函数,这个函数的参数c就是专门用来取消当前请求的函数。 - 我们把这个取消函数
c赋值给外部的cancel变量,之后只要调用cancel(),就能立刻终止当前的请求。
useEffect里的取消逻辑全解析
每次Effect执行时绑定取消开关:
每当query(搜索关键词)、pageNumber(页码)或者users变化时,useEffect都会重新执行,这时会给新发起的axios请求绑定一个新的CancelToken,同时拿到对应的取消函数cancel。清理函数自动取消旧请求:
useEffect的返回值是一个清理函数,这个函数会在两种场景下执行:- 组件被卸载时;
- 当前Effect即将重新执行(比如用户改了搜索关键词,触发Effect重新运行)。
这里调用cancel(),就会把上一次还没完成的请求直接取消,避免它返回后干扰当前的状态。
区分取消错误和真正的请求错误:
请求被取消时,Axios会抛出一个特殊的取消错误,所以在catch块里加了if (axios.isCancel(e)) return——这种主动取消的情况不属于“请求失败”,不需要设置error状态,直接跳过错误处理逻辑就行。
额外补充:代码里的一个小问题
setHasMore(users.length >= res.data.total)这里有个小bug:users是当前的状态值,而我们刚把新数据合并到users里,正确的判断应该用更新后的长度,改成:
setHasMore(prevState.length + res.data.users.length >= res.data.total)
这样才能准确判断是否还有更多数据。
内容的提问来源于stack exchange,提问作者ghophri
相关产品推荐
相关产品推荐

