React上传组件进度条卡在0%不动怎么办?

Top丶颖昕 阅读 54

最近在做一个文件上传功能,想给用户实时显示上传进度。按照教程用了axios的上传进度事件,但进度条一直卡在0%不动,上传完成后也没显示100%。尝试过在useEffect里加依赖数组,也检查过文件对象没问题。

这是我的组件代码:


import axios from 'axios';

function UploadForm() {
  const [progress, setProgress] = useState(0);

  const handleUpload = async (file) => {
    try {
      const response = await axios.post('/api/upload', file, {
        onUploadProgress: (event) => {
          const percent = Math.round((event.loaded / event.total) * 100);
          setProgress(percent); // 这里可能有问题?
        }
      });
      console.log('上传成功', response);
    } catch (error) {
      console.error(error);
    }
  };

  return (
    <div>
      <progress value={progress} max="100" />
      <button onClick={() => handleUpload(selectedFile)}>上传</button>
    </div>
  );
}

控制台没报错,但进度条就是不动。是不是useState更新不够快?或者需要手动刷新UI?之前用setTimeout模拟进度条还能动,真实上传时就不行了…

我来解答 赞 8 收藏
二维码
手机扫码查看
2 条解答
Air-心霞
这个问题我之前也碰到过,最常见的原因是没用FormData包装文件。

axios默认是JSON格式发送数据的,你直接传file对象会被转成JSON,后端根本收不到正确的文件数据,进度事件自然就不会触发。

改一下,把file用FormData包起来:

import axios from 'axios';
import { useState } from 'react';

function UploadForm() {
const [progress, setProgress] = useState(0);
const [selectedFile, setSelectedFile] = useState(null);

const handleUpload = async (file) => {
try {
const formData = new FormData();
formData.append('file', file); // 关键在这里

const response = await axios.post('/api/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data' // 最好也加上这个
},
onUploadProgress: (event) => {
const percent = Math.round((event.loaded / event.total) * 100);
setProgress(percent);
}
});
console.log('上传成功', response);
} catch (error) {
console.error(error);
}
};

return (
<div>
<input type="file" onChange={(e) => setSelectedFile(e.target.files[0])} />
<progress value={progress} max="100" />
<button onClick={() => selectedFile && handleUpload(selectedFile)}>上传</button>
</div>
);
}


另外你说控制台没报错,但我看你代码里用了useState却没import,这应该会报undefined错的吧?你检查一下是不是有控制台错误被忽略了。

还有一个小问题:如果后端没开CORS或者上传接口本身有问题,进度事件也不会正常触发,你可以用浏览器的Network面板看看请求有没有发出去、状态码对不对。
点赞
2026-03-10 22:05
UI丽珍
UI丽珍 Lv1
问题出在你传给axios的file不是正确的FormData格式。直接传文件对象,后端可能收不到正确数据,进度也拿不到。改成这样:

const handleUpload = async (file) => {
const formData = new FormData();
formData.append('file', file);

try {
await axios.post('/api/upload', formData, {
onUploadProgress: (event) => {
setProgress(Math.round((event.loaded / event.total) * 100));
}
});
} catch (error) {
console.error(error);
}
};


差不多就行,记得后端也要对应处理FormData。
点赞 8
2026-02-02 10:02