Reputation: 147
I have the following code for uploading multiple images in my React app. The problem is that console.log(e)
prints Progress Event object with all its values, but when I want to update my state I still be the default values, null, 0, []
. I understand that onload
is asynchronous and that might be the reason they are not updated. Technically the code is working when I upload file one by one. When I select multiple files at once, only the first one is being displayed. What am I doing wrong here?
const [fileUpload, setFileUpload] = useState(null);
const [filesUploaded, setFilesUploaded] = useState([]);
const [filesUploadedCount, setFilesUploadedCount] = useState(0);
const handleFileUpload = (e) => {
if (filesUploadedCount === 5 || e.currentTarget.files > 5) {
return;
}
const files = e.currentTarget.files;
console.log(files.length);
console.log(e.currentTarget.files);
Array.from(files).forEach((file: any) => {
const reader = new FileReader();
reader.onload = (e) => {
console.log(e); // Progress Event {}
setFileUpload(e.target.result);
setFilesUploadedCount(filesUploaded.length + 1);
setFilesUploaded([...filesUploaded, e.target.result]);
console.log(fileUpload); // null
console.log(filesUploaded); // []
console.log(filesUploaded.length); // 0
console.log(filesUploadedCount); // 0
};
reader.readAsDataURL(file);
});
};
Here I display them.
{filesUploaded?.map((file, index) => {
return (
<ItemImage
key={index}
src={file}
handleRemoveFile={handleRemoveFile}
/>
);
})}
Upvotes: 1
Views: 982
Reputation: 1396
useState is also asynchronous operation, so you should not rely on their values for calculating the next state. Pass a function like this. You may not see in your console.log because of that.
setFilesUploaded(prevState => [...prevState, e.target.result]);
Upvotes: 2