user12051965
user12051965

Reputation: 147

React upload multiple files at once

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

Answers (1)

Vo Quoc Thang
Vo Quoc Thang

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

Related Questions