组件没有像 React 上应该的那样经常更新
Component not updating as often as it should be on 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)
我正在做一个基于 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)