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

React Native中react-native-blob-util多下载任务无法取消的问题

问题分析

核心问题在于:React函数组件中用let声明的downloadTasks数组,会在组件每次重新渲染时被重新初始化。尽管下载过程中你往数组里添加了任务,但组件重新渲染后这个变量会被重置为空数组,导致取消操作时无法访问到之前的任务。

解决方案

改用useRef保存下载任务数组,useRef的.current属性在组件整个生命周期内会保持引用不变,不会随渲染重置。

修改步骤

  1. 导入useRef(未导入的话需要添加)
  2. 用useRef替代let声明任务数组
  3. 在下载和取消逻辑中操作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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 22:17:40