reactjs - React Hooks FileReader。警告:unstable_flushDiscreteUpdates:React 已经在渲染时无法刷新更新
问题描述
选择文件后,我尝试在FileWidgetDropzone上使用FileReader 。
我使用带有onLoadCallback的函数:
const readFile = (file: any, onLoadCallback: any) => {
var reader = new FileReader();
reader.onload = onLoadCallback;
reader.readAsArrayBuffer(file);
};
我使用 State 来存储来自onLoadCallback函数的结果数据(fileMetadata):
const [loadedFileReader, setLoadFileReader] = useState(false);
const [fileMetadata, setFileMetadata] = useState<IFileMetadata>(
new FileMetadataValues()
);
const [files, setFiles] = useState<any[]>([]);
在onLoadCallback中使用readFile和更新状态的函数:
const getFileExif = (file: any) => {
setLoadFileReader(true);
readFile(file, function(e: any) {
const data = ... e.target.result;
if (data) {
var model = new FileMetadataValues();
...
setFileMetadata(model);
setLoadFileReader(false);
}
}
});
};
使用 Effect获取额外的文件数据
useEffect(() => {
if (files.length >0 && !loadedFileReader) {
getFileExif(files[0]);
return () => {
files.forEach(file => URL.revokeObjectURL(file.preview));
};
}
}, [files]);
return (
<div>
<FileWidgetDropzone
...
每次都会重新渲染该组件,然后从 getFileExif 函数调用状态更改(总共 4 次)。
当我放置调试器时;返回之前(...我收到一个错误浣熊控制台日志:警告 - index.js:1警告:unstable_flushDiscreteUpdates:React 已经呈现时无法刷新更新。
请帮助为此示例开发更有效的解决方案。
解决方案
使用 React Dropzone 时找到了解决方案。我使用承诺。
父组件:
const [files, setFiles] = useState<any[]>([]);
const [filesMetadata, setFilesMetadata] = useState<any[]>([]);
子组件:
const getFilesMetadata = (acceptedFiles: object[]) => {
const files = [...acceptedFiles];
parseMeta(files);
};
files.forEach((file: any) => {
let promise = new Promise(resolve => {
const reader = new FileReader();
reader.onabort = () => console.log("file reading was aborted");
reader.onerror = () => console.log("file reading has failed");
reader.onload = () => {
...
resolve(model);
};
reader.readAsArrayBuffer(file);
});
promises.push(promise);
});
Promise.all(promises).then((data) => {
setFilesMetadata(
data.map((fileMeta: FileMetadataValues) =>
Object.assign(fileMeta, fileMeta)
)
);
});
const onDrop = useCallback(
acceptedFiles => {
setFiles(
acceptedFiles.map((file: object) =>
...
)
);
getFilesMetadata(acceptedFiles);
},
[setFiles, getFilesMetadata]
);
const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop });
推荐阅读
- typescript - 如何在语句中添加/删除修饰符?
- c++ - 在分段错误处理程序中调用 pthread_exit 时终止调用而没有活动异常
- c++ - 在 C++ 中的派生类之间共享公共代码
- struct - 对 malloced struct 属性的第二次访问会使程序崩溃
- java - 使用 ASM 检测 java lambda
- php - WooCommerce - 购物车验证的自定义功能
- java - 将长数字添加到 INTEGER SQLite
- python - 多个脚本在python中使用相同的数据访问同一个模块?
- python - 将列添加到过滤数据集
- java - 从远程设备上的 Jar 中读取文本文件