javascript - 使用 React Drop zone 时,文件附件花费了太多时间
问题描述
我正在使用该react-dropzone
库从浏览器中拖动或选择文件。
我有以下组件让用户选择多个文件。一切正常,除了如果用户选择更多文件,比如说 2 个或更多大小为 1 MB 的文件,则选择文件需要时间。如果文件数越多,选择用户选择的文件所需的时间就越多。根据我对react-dropzone
文档的阅读,它会在上传后立即处理文件。所以我尝试设置 autoProcessQueue='false'。但没有运气。
我只想让用户在选择文件后和发送到后端服务器之前选择所有文件而不阻塞 30 或 40 秒。我进行了调试,并且在 DropZone 内部处理了所有文件之后达到了 setSelectedUserFiles()。我不确定是否有办法禁用它并让它作为表单的最终提交的一部分处理或单击按钮。如果我们不能达到同样的效果,有没有办法向用户显示正在附加文件的消息。任何帮助将不胜感激。
下面是我的反应组件
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>
)
}
解决方案
尝试这样的事情
- 创建仅发送文件的单独 api 组件,
- 您的具有 dropzone 的组件在本地管理文件上传,而不发送到服务器。您只需单击按钮并发送它。这个链接非常有帮助: https ://www.robinwieruch.de/react-hooks-fetch-data
第一个组件:
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];
};
第二部分:
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>
)
}
推荐阅读
- python - FileNotFoundError - 从 WindowsPath 对象打开图像时遇到问题
- spring - Spring:如何访问位于 jar 之外的 txt 文件?
- .htaccess - .htaccess 在 URLS 末尾强制使用斜杠
- python - 如何创建带有事件的键盘侦听器?(Python)
- google-sheets - 如何从网络表单中的 Google 表格数据生成填充的 PDF?
- react-native - React Native 使用 useSelector 保持滚动视图位置
- java - 使@GeneratedValue 开始一个具有特定值的序列
- angular - 用 jest 测试角度组件会给出 resolveComponentResources
- regex - 如何将月份和日期的一位数日期格式更改为月份和日期的两位数
- maven - 查看多版本 JAR (MRJAR) 的版本源