File attachment is taking too much time when using React Drop zone

I am using the react-dropzone library to drag or select files from the browser.

I have the below component to let the user select multiple files. Everything works except that if the user chooses more files let say 2 or more files with size 1 MB, the selection of documents is taking time. If the number of files is more, the more time it takes to selected the user-selected files.
As per my reading of the react-dropzone docs, it processes files as soon as it uploads. So I tried setting autoProcessQueue=’false’.
but no luck.

I just want to let the user select all the files without blocking for 30 or 40 secs after selecting files, and before send to the backend server.
I did the debug and the setSelectedUserFiles() is reached after all the files are processed internally by the DropZone. I am not sure if there is a way to disable it and let it process as part final submission of the form or click on the button.
In case if we can’t achieve the same, is there a way to show the message to the user that files are being attached.
Any help will be appreciated.

Below is my react component

const SelectUserFiles = () => {
  const [userName,setUserName] = userState('TestUser')
  const [selectedUserFiles,setSelectedUserFiles] = userState([])
 
  const handleUserFileUpload = async (acceptedFiles) => {
      await setSelectedUserFiles(acceptedFiles)
    }
  
  return (
    <div className='myClass'>Select Files</div>
      <Dropzone
        //autoProcessQueue='false'
        accept={'.pdf'}         
        onDrop={acceptedFiles => handleUserFileUpload(acceptedFiles)}
      >…</Dropzone>
    </div>
    
    <MyButton>
    //logic to send the files to backend axios with the files selectedUserFiles 
    </MyButton>
  )
}

6 thoughts on “File attachment is taking too much time when using React Drop zone”

  1. Try something like this

    1. Create separate api component that only send files,
    2. Your component that has dropzone manages file upload
      locally without sending to the server. You only click the button
      and send it.

    first component:

    export const useApiCall = () => {
        const [data, setData] = useState({});
    
        const [selectedAllUserFiles, setSelectedAllUserFiles] = useState([]);
    
        const [isLoading, setIsLoading] = useState(false);
        const [isError, setIsError] = useState(false);
    
        useEffect(() => {
            const pushToserver = async () => {
                setIsError(false);
                setIsLoading(true);
                try {
                    const formData = new FormData();
                    Array.from(selectedAllUserFiles).forEach((file) => {
                        form.append('fileData', file);
                    });
    
                    const result = await axios.post(someUrl, formData);
    
                    setData(result.data);
                } catch (error) {
                    setIsError(true);
                }
    
                setIsLoading(false);
            };
            if (selectedAllUserFiles.length > 0) {
                pushToserver();
            }
        }, [selectedAllUserFiles]);
    
        //passing reference to the calling component
    
        return [{ data, isLoading, isError }, setSelectedAllUserFiles];
    };
    

    Second component:

    const SelectUserFiles = () => {
      const [userName,setUserName] = userState('TestUser')
    
      const [selectedUserFiles,setSelectedUserFiles] = userState([])
    
      //Ref from logical api call component
      const [{ data, isLoading, isError }, setSelectedAllUserFiles] = useApiCall();//new component
    
      const handleUserFileUpload = async (acceptedFiles) => {
            if (acceptedFiles) {
                acceptedFiles.map((file) => {
                    setSelectedUserFiles((selectedUserFiles) => selectedUserFiles.concat(file));
                    return selectedUserFiles;
                });
            }
          
          //await setSelectedUserFiles(acceptedFiles)
        }
      
      return (
        <div className='myClass'>Select Files</div>
          <Dropzone
            //autoProcessQueue='false'
            accept={'.pdf'}         
            onDrop={acceptedFiles => handleUserFileUpload(acceptedFiles)}
          >…</Dropzone>
        </div>
        
        //on click call api and pass collected user files all together
        <MyButton onClick={()=>setSelectedAllUserFiles(selectedUserFiles)}>
        //logic to send the files to backend axios with the files selectedUserFiles 
        </MyButton>
      )
    }
    
    Reply

Leave a Comment