reactjs - 组件没有像在 React 上那样频繁地更新
问题描述
我正在开发一个基于 NextJS 的项目。我想要完成的是带有进度条的文件上传。上传工作得很好,但我的组件的渲染在所有进度中只更新了一两次。这是我用来上传文件的方法(使用 axios):
static async uploadFileToCenter(centerId:string, file:any, progressCallback) {
const formData = new FormData();
formData.append(`uploaded_file`, file);
return api.post(`/centers/${centerId}/uploadFiles`, formData, {
headers: {
'content-type': 'multipart/form-data'
},
onUploadProgress: (progressEvent) => { progressCallback(progressEvent, file) },
});
}
这是我用于实际组件渲染的代码:
const [files, setFiles] = useState([]);
const progressCallback = (progressEvent, file) => {
const fileIndex = files.findIndex(f => f.name === file.name);
const progress: number = Math.ceil((progressEvent.loaded as number * 100) / progressEvent.total);
console.log(progress);
files[fileIndex].progress = progress;
setFiles(files);
}
useEffect(() => {
if(!files || files.length === 0) {
return;
}
setUploading(true);
files.forEach((file) => {
CenterService.uploadFileToCenter(center._id, file, progressCallback).then(response => {
const uploadedFile = response && response?.data?.data?.url;
const tempFiles = (center?.files) ? [...center.files, uploadedFile] : uploadedFile;
if (tempFiles) {
formik.setFieldValue('files', uniq(tempFiles));
}
setUploading(false);
});
});
}, [files]);
function Thumbs() {
return <div className="uploaded-files-container">
{files.map(file => (
<div className="uploaded-file-container" key={file.name}>
<div className="thumbnail-container">
<div className="thumbnail" style={{backgroundImage: `url(${file.preview || '/_next/static/media/bg-searchTreatment.aa8648dea68731269b666fbe58cd505f.jpg'})`}}></div>
</div>
<div className="details-container">
<div className="progress-indicator" style={{width: `${file.progress}%`}}></div>
{ file.progress && <div className="progress-number">{ file.progress }%</div> }
<div className="file-name">
{file.name}
</div>
<div className="file-size">
{(file.size/1024).toFixed(0)}KB
</div>
</div>
<div className="actions-container">
{ file.progress && file.progress < 100 && <Spinner /> }
{ !uploading && <a onClick={() => removeImage(file)}><Image src="/assets/remove.svg" height="30" width="30" /></a> }
</div>
</div>
))}
</div>
};
正如您在此处看到的,我可以在控制台上看到所有进度,但不会反映在我的 Thumbs 组件上:
也许我遗漏了一些明显的东西,因为我对 React 还很陌生。
解决方案
在您的进度回调中:
files[fileIndex].progress = progress;
setFiles(files);
这可能是因为您files
使用与以前相同的参考进行更新,您可能需要在调用之前进行复制setFiles
const newFiles = [...files]
newFiles[filesIndex].progress = progress;
setFiles(newFiles)
推荐阅读
- tensorflow - 如何在异步 Actor Critic 方法中实现 TensorFlow 模型并行性?
- algorithm - 收集物品集的优化算法
- reactjs - 尝试打印具有数组的对象时出错
- ruby-on-rails - 尝试 db:migrate 在 heroku 内部,迁移失败
- batch-file - 使用 Batch 或 VBS 将文件夹和子文件夹移动到另一个文件夹
- javascript - 如何创建可重用的 AJAX 调用函数并从返回的对象中提取不同的值
- php - 使用php以固定顺序旋转广告
- node.js - App Engine 上的 React.js 作为服务查询作为同一项目中另一个服务运行的 API
- angular - 它是服务还是提供者?被 Angular 教程弄糊涂了
- sql - 将 PostgreSQL 表连接到另一个表的列