React组件卸载时用React Query 3.39.2取消待处理API请求遇问题
问题分析与解决方案
原代码存在的问题
- 变量名拼写错误:
const queryClinet = useQueryClient();中queryClinet应为queryClient,虽然你提到代码能进入if块,但这个拼写错误可能在实际运行中引发异常。 - 依赖项设置错误:useEffect的依赖是
window.location.href,这意味着清理函数只会在URL变化时执行,而非组件卸载时。如果你的需求是组件卸载时取消请求,这个依赖完全不符合预期。 - 未过滤待处理请求:
getQueryCache().getAll()会返回所有缓存的请求(包括已完成的),取消已完成的请求毫无意义,必须只针对**状态为loading(待处理)**的请求操作。 - cancelQueries使用方式不够精准:直接遍历queryCache并调用
cancelQueries,不如利用React Query内置的predicate函数更高效可靠,尤其是针对动态queryKey的场景。
修正后的代码
const queryClient = useQueryClient(); useEffect(() => { return () => { // 匹配所有包含指定关键词的待处理请求并取消 queryClient.cancelQueries({ predicate: (query) => { return query.queryKey.includes('partOfMyKey') && query.state.status === 'loading'; } }); }; }, [queryClient]); // 依赖queryClient,组件卸载时自动执行清理函数
关键修正点说明
- 调整依赖项:将依赖改为
[queryClient],确保组件卸载时触发清理函数;如果需要在URL变化时也取消请求,可添加window.location.href到依赖数组。 - 使用predicate函数:直接通过
cancelQueries的配置参数筛选目标请求,无需手动遍历queryCache,React Query会自动处理所有匹配的待处理请求。 - 过滤loading状态:只取消真正处于待处理状态的请求,避免无效操作。
如果你的场景确实需要在URL变化时执行取消操作,可修改依赖数组为[queryClient, window.location.href],此时清理函数会在URL变化和组件卸载时都执行。
内容的提问来源于stack exchange,提问作者Soumya Sagnik Khanda
相关产品推荐
相关产品推荐

