Reputation: 1655
I am trying to display the progress for the files uploads in my React app.
First, I have created this function to upload multiple files:
const [files, setFiles] = useState([])
const saveDocuments = () => {
try {
files.forEach((file) => {
axios.post("/api/documents", formData, {
let formData = new FormData();
formData.append("attached_file", file);
formData.append("name", file.name);
headers: {
"X-CSRFTOKEN": getCookie("csrftoken"),
"Content-Type": "multipart/form-data",
},
onUploadProgress: (progressEvent) => {
const percentCompleted = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
);
file.progress = percentCompleted;
console.log(percentCompleted);
},
});
});
} catch (e) {
console.log(e);
}
};
With this code, I can see in the console the percentCompleted
value.
And in my render function, I'm trying to display this progress value:
return(
<ul>
{files.map((file, index) => (
<li key={index} >
<div>{file.name}</div>
<div>{file.progress} %</div>
</li>
))}
</ul>;
)
The progress value does not display ; but the react dev tools shows the progress value in the state.
I guess I am not updating correctly the state of my file
object. How can I deal with this? Thanks for helping.
Upvotes: 2
Views: 6226
Reputation: 1655
So I found out the solution, I have to create a copy of my array files
with a new key progress
which has the value of percentCompleted
const saveDocuments = () => {
try {
files.forEach((file) => {
axios.post("/api/documents", formData, {
let formData = new FormData();
formData.append("attached_file", file);
formData.append("name", file.name);
headers: {
"X-CSRFTOKEN": getCookie("csrftoken"),
"Content-Type": "multipart/form-data",
},
onUploadProgress: (progressEvent) => {
const percentCompleted = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
);
// Create copy of file
let newFile = file;
// ... and set the progress
newFile.progress = percentCompleted;
// Create copy of files array
let filesCopy = [...files];
// Find the index of the file object
let fileIndex = filesCopy.findIndex((el) => el.name === file.name);
//... and replace the object with the new one containing the [progress] key
filesCopy[fileIndex] = newFile;
// Finally, update the state
setFilesUploaded([...filesCopy]);
file.progress = percentCompleted;
},
});
});
} catch (e) {
console.log(e);
}
};
Then, the render function returns the new array containing objects with the progress
key:
return(
<ul>
{filesUploaded.map((file, index) => (
<li key={index} >
<div>{file.name}</div>
<div>{file.progress} %</div>
</li>
))}
</ul>;
)
Upvotes: 3