I am trying to read a JSON file from a hard drive that has been either selected by a user or dragged and dropped. I'm a little unsure how it should work and I think I have an issue with the fact that FileReader.readAsText is async. Anyways, made a drop zone component which works fine and users can also select a file. Here is the relevant parts of my code:
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>
);
};
The console log of parsedFile is null but if I set a debugger statement in the onload I can see the contents of the file being read. Why can't I get the contents of the file out?