React Native中react-native-blob-util多下载任务无法取消的问题
问题分析
核心问题在于:React函数组件中用let声明的downloadTasks数组,会在组件每次重新渲染时被重新初始化。尽管下载过程中你往数组里添加了任务,但组件重新渲染后这个变量会被重置为空数组,导致取消操作时无法访问到之前的任务。
解决方案
改用useRef保存下载任务数组,useRef的.current属性在组件整个生命周期内会保持引用不变,不会随渲染重置。
修改步骤
- 导入
useRef(未导入的话需要添加) - 用
useRef替代let声明任务数组 - 在下载和取消逻辑中操作
ref.current
修改后的完整代码
// 确保导入useRef import { useRef } from 'react'; // 用useRef保存任务数组,初始化为空 const downloadTasksRef = useRef<StatefulPromise<FetchBlobResponse>[]>([]); // 开始下载函数 const handleDownloadOfflineData = async () => { try { // 新下载开始前清空旧任务(可选,根据业务需求调整) downloadTasksRef.current = []; await Promise.all( uniqueMediaFiles.map((media, i) => { const task = ReactNativeBlobUtil.config({ path: `${cacheDir}/${INTERACTIVE_TOUR_DIR}/${oneInteractiveTourDetailsMobile.id}/media/${media.bucketPath}`, }) .fetch('GET', `${BUCKET_PATH}${media.bucketPath}`) .progress((received, total) => { console.log('Progress: ', received / total); }); // 往ref的current数组中添加任务 downloadTasksRef.current.push(task); console.log('PUSH TASK: ', downloadTasksRef.current.length); return task; }), ).then(async _responses => { // 下载完成后清空任务数组 downloadTasksRef.current = []; }); } catch (err) { // 出错时清空任务数组 downloadTasksRef.current = []; } }; // 取消下载函数 const handleCancelDownload = async () => { console.log('CANCEL TASKS: ', downloadTasksRef.current.length); downloadTasksRef.current.forEach(task => { task.cancel(); }); // 取消后清空任务数组,避免重复操作 downloadTasksRef.current = []; };
额外说明
- 为什么不用
useState?因为useState更新会触发组件重新渲染,而我们仅需保存任务引用,无需触发渲染,useRef更轻量合适。 - 在下载开始、完成、出错、取消后清空任务数组,可避免内存泄漏或重复操作已完成的任务。
内容的提问来源于stack exchange,提问作者SlothOverlord
相关产品推荐
相关产品推荐

