从本地硬盘读取 JSON 文件并解析为 React 应用程序

read JSON file from local hard drive and parse into react app

我正在尝试从已被用户 select 编辑或拖放的硬盘读取 JSON 文件。我有点不确定它应该如何工作,我认为我对 FileReader.readAsText 是异步的这一事实有疑问。无论如何,制作了一个工作正常的拖放区组件,用户也可以 select 一个文件。这是我的代码的相关部分:

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 的控制台日志为空,但如果我在 onload 中设置调试器语句,我可以看到正在读取的文件的内容。为什么我不能把文件的内容取出来?

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

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

输入错误:

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

文件reader代码:

const fileReader = new FileReader();

fileReader.readAsText(e.dataTransfer.files[0]);

fileReader.onload = () => {
  setParsedFile(fileReader.result);
};