从本地硬盘驱动器读取 JSON 文件并解析到 react 应用程序中



我正在尝试从用户选择或拖放的硬盘驱动器中读取JSON文件。我有点不确定它应该如何工作,我想我对FileReader.readAsText是异步的事实有问题。无论如何,制作了一个工作正常的拖放区组件,用户也可以选择一个文件。以下是我的代码的相关部分:

const DropZone = () => {
const [files, setFiles] = useState([]);
const [parsedFile, setParsedFile] = useState(null);
const onDrop = async (e) => {
e.preventDefault();
if (disabled) return;
setFiles([...e.dataTransfer.files]);
const fileReader = new FileReader();
await fileReader.readAsText(e.dataTransfer.files[0]);
fileReader.onload = (e) => {
setParsedFile(JSON.parse(e.target.result));
};
// e.dataTransfer.clearData();
// setDragging(false);
};
const renderHasFiles = () => {
// console.log('files: ', files);
return (
<Fragment>
<StyledIcon iconName="cloud_done" size="extraLarge" color={alertColors.SUCCESS} />
<div>Got em!</div>
<FileList>
<FileListHeader>
<TableHeader>File Name</TableHeader>
<TableHeader align="right">Size</TableHeader>
</FileListHeader>
<FileListContent>
{renderFileList()}
</FileListContent>
</FileList>
<ButtonContainer>
<ClearButton onClick={(e) => {e.preventDefault(); e.stopPropagation(); setFiles([]);}}>
Clear Files
</ClearButton>
<StyledButton onClick={(e) => { e.preventDefault(); e.stopPropagation(); submitButtonCallback(files, parsedFile); }}>
{submitButtonText}
</StyledButton>
</ButtonContainer>
</Fragment>
);
};
return (
<DropZoneContainer
width={width}
height={height}
disabled={disabled}
dragging={dragging}
onClick={() => openFileDialog()}
onDragOver={(e) => onDragOver(e)}
onDrop={(e) => onDrop(e)}
>
{files.length === 0 ? renderNoFiles() : renderHasFiles()}
</DropZoneContainer>
);
};

parsedFile 的控制台日志为 null,但如果我在 onload 中设置调试器语句,我可以看到正在读取的文件的内容。为什么我无法获取文件的内容?

拼写错误:

const [parsedFile, setParsedFile] = useState(null);

文件读取器代码:

const fileReader = new FileReader();
fileReader.readAsText(e.dataTransfer.files[0]);
fileReader.onload = () => {
setParsedFile(fileReader.result);
};

您正在尝试打印parsedFile,但在状态下称为parsedFiled。您还将在onload回调设置状态之前打印值。尝试将打印移动到回调函数中。

onload回调函数是异步的,因此不能在调用该值后立即使用该值,因为无法保证该函数已解析。为了使用文件内容,您可以执行以下操作之一:将相关代码放在渲染函数中,以便它可以对状态更改做出反应;编写代码并将其插入回调函数,以便在内容可用时调用它;使用同步读取函数或将异步函数包装在 promise 中,以便您可以对其解析方式有一个期望(例如await承诺并立即使用内容(。

最新更新