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

React中使用setState无法重置Blob数组?照片上传异常求助

问题分析与解决方案

你的核心问题源于React状态更新的异步特性,以及闭包导致的旧状态捕获,具体问题点:

  • setBlobs是异步操作,直接用[...blobs, ...]会捕获闭包中的旧状态,连续拍摄时会丢失之前的更新
  • checkLength在fetch请求完成前就被调用,此时blobs还未更新,判断逻辑完全基于旧值
  • 判断条件>=2不符合「每3张上传」的需求,逻辑匹配错误

修复后的代码

import { useState, useEffect } from 'react';

// 组件内部代码
const [blobs, setBlobs] = useState([]);

const capturePhoto = async () => {
  const photo = await camera.current.takePhoto();
  try {
    const res = await fetch(photo.path);
    // 使用函数式更新,确保基于最新状态添加新blob
    setBlobs(prevBlobs => [...prevBlobs, res._bodyBlob]);
  } catch (err) {
    console.log('err', err);
  }
};

// 监听blobs状态变化,达到3张时执行上传与重置
useEffect(() => {
  const handleBatchUpload = async () => {
    if (blobs.length === 3) {
      const datestring = new Date().toLocaleString('de-DE');
      // 等待所有上传完成后再重置状态,避免数据丢失
      await Promise.all(
        blobs.map((blob, index) => uploadFile(blob, `${datestring}/${index + 1}.jpg`))
      );
      setBlobs([]);
      sendNotification('Photos uploaded');
      toggleDialog();
    }
  };

  handleBatchUpload();
}, [blobs]); // 依赖blobs,每次状态变更都触发检查

关键修改说明

  1. 函数式状态更新:setBlobs(prevBlobs => [...prevBlobs, res._bodyBlob]),确保每次更新都基于最新的状态值,彻底解决闭包导致的状态覆盖问题。
  2. useEffect监听状态:将上传逻辑移至useEffect中,当blobs数组长度达到3时自动触发操作,保证判断的是最新的状态长度。
  3. 等待全部上传完成:用Promise.all等待所有上传请求结束后再重置状态,避免上传未完成就清空数组引发的异常。
  4. 修正判断条件:改为blobs.length === 3,严格匹配「每积累3张就上传」的需求。

内容的提问来源于stack exchange,提问作者Felkru

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 20:22:54