选择文件后,我尝试在FileWidgetDropzone上使用FileReader。
我使用带有onLoadCallback的函数:
const readFile = (file: any, onLoadCallback: any) => {
var reader = new FileReader();
reader.onload = onLoadCallback;
reader.readAsArrayBuffer(file);
};
我使用 State 来存储来自onLoadCallback函数的结果数据(文件元数据(:
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);
}
}
});
};
使用效果获取其他文件数据
useEffect(() => {
if (files.length >0 && !loadedFileReader) {
getFileExif(files[0]);
return () => {
files.forEach(file => URL.revokeObjectURL(file.preview));
};
}
}, [files]);
return (
<div>
<FileWidgetDropzone
...
每次重新渲染此组件,然后从getFileExif函数调用状态更改(总共4次(。
当我把调试器;在返回之前(...我收到一个错误 coon 控制台日志: 警告 - 索引.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 });