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

如何正确实现React+ChakraUI项目中的图片上传进度条

问题解决方法

问题根源

首次上传完成后,你没有重置progress状态为初始值0,该状态会停留在100的满额状态。后续只要选中新文件触发渲染,进度条就会直接读取这个遗留的满额值,因此出现你描述的问题。

修复步骤

  • 选中新文件时重置进度、错误状态,避免上一次上传的状态残留
  • 上传结束(成功/失败)时,补充重置进度的逻辑,保证单次上传流程结束后所有状态复位
  • (可选)删除代码中未使用的拼写错误状态curretFile,减少冗余代码

修正后完整代码

import * as React from "react";
import { Button, Progress } from "@chakra-ui/react";
import { useState } from "react";
import axios from "axios";
import { baseUrl } from "../config";

function Upload(props) {
  const [selectedFile, setSelectedFile] = useState(null);
  const [progress, setProgress] = useState(0);
  const [error, setError] = useState(null);

  function fileSelectedHandler(event) {
    const file = event.target.files[0];
    setSelectedFile(file);
    // 选中新文件时重置进度和错误状态
    setProgress(0);
    setError(null);
  }

  const fileUploadHandler = (event) => {
    const fd = new FormData();
    fd.append("image", selectedFile, selectedFile.name);

    axios
      .post(`${baseUrl}/upload`, fd, {
        headers: {
          "Content-Type": "multipart/form-data",
        },
        onUploadProgress: (event) => {
          setProgress(Math.round((100 * event.loaded) / event.total));
        },
      })
      .then((res) => {
        props.onSuccessfulUpload();
        setSelectedFile(null);
        setError(null);
        // 上传成功重置进度
        setProgress(0);
      })
      .catch((error) => {
        setSelectedFile(null);
        setError(error);
        // 上传失败也重置进度
        setProgress(0);
      });
  };

  const fileData = () => {
    if (selectedFile) {
      if (
        selectedFile.type === "image/jpeg" ||
        selectedFile.type === "image/png"
      ) {
        return (
          <div>
            {error && <div>file too large!!</div>}
            <Button colorScheme='teal' size='sm' onClick={fileUploadHandler}>
              Upload!
            </Button>
            <Progress value={progress} min='0' max='100' width='40' />
          </div>
        );
      } else {
        return (
          <div>
            <h4>Please choose an image to upload</h4>
          </div>
        );
      }
    } else {
      return (
        <div>
          <h4>Choose Photos</h4>
        </div>
      );
    }
  };

  return (
    <div>
      <input type='file' onChange={fileSelectedHandler} />
      {fileData()}
    </div>
  );
}

export default Upload;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 17:15:02