I have a file upload component. The behavior is simple: I send one upload request to the back-end per file and as the upload progress increase, I have a bar that should increase with it.
I have a state that holds every selected file and their respective progress, as such:
interface IFiles {
file: File;
currentProgress: number;
}
const [selectedFiles, setSelectedFiles] = useState<IFiles[]>([]);
And when the user clicks the upload button, this function will be triggered and call uploadFile
for each file in my array state.
const sendFilesHandler = async () => {
selectedFiles.map(async (file) => {
const fileType = file.file.type.split('/')[0];
const formData = new FormData();
formData.append(fileType, file.file);
formData.append('filename', file.file.name);
await uploadFile(formData, updateFileUploadProgress);
});
};
Here is what the uploadFile
function looks like.
const uploadFile = async (body: FormData, setPercentage: (filename: string, progress: number) => void) => {
try {
const options = {
onUploadProgress: (progressEvent: ProgressEvent) => {
const { loaded, total } = progressEvent;
const percent = Math.floor((loaded * 100) / total);
const fileName = body.get('filename')!.toString();
if (percent <= 100) {
setPercentage(fileName, percent)
}
}
};
await axios.post(
"https://nestjs-upload.herokuapp.com/",
body,
options
);
} catch (error) {
console.log(error);
}
};
As you can see, when uploadProgress is triggered it should inform call setPercentage function, which is:
const updateFileUploadProgress = (fileName: string, progress: number) => {
console.log('Entrada', selectedFiles);
const currentObjectIndex = selectedFiles.findIndex((x) => fileName === x.file.name);
const newState = [...selectedFiles];
newState[currentObjectIndex] = {
...newState[currentObjectIndex],
currentProgress: progress,
};
setSelectedFiles(newState);
console.log('Saída', newState);
};
And this function should only update the object of my state array where the filenames match. However, it is overriding the whole thing. The behavior is as follows:
So it seems that everything is fine as long as I am updating the same object. But in the moment onUploadProgress
is triggered to another object, selectedFiles
states becomes its initial state again. What am I missing to make this work properly?