[개발 기록] File Reader

블루·2022년 11월 11일
1

1. Search

FileReader

  • 웹 애플리케이션이 비동기적으로 데이터를 읽기 위하여 읽을 파일을 가리키는 File 혹은 Blob 객체를 이용해 파일의 내용을 읽고 사용자의 컴퓨터에 저장하는 것을 가능하게 해준다.

FileReader.onload

  • FileReader가 성공적으로 파일을 읽어들였을 때 트리거되는 이벤트 핸들러이다.

FileReader.onerror

  • 읽기 동작에 에러가 생길 때 트리거되는 이벤트 핸들러이다.

FileReader.onprogress

  • 컨텐츠를 읽는 동안 호출된다.

2. Coding

import React, { useRef } from 'react';
import styled from '@emotion/styled';
import { Editor } from '@toast-ui/react-editor';
import '@toast-ui/editor/dist/toastui-editor.css';

const Container = styled.div`
  box-sizing: border-box;
  width: 100%;
  height: 100vh;
  display: flex;
  flex-direction: column;
  padding: 30px 25px;
`;


const ButtonContainer = styled.div`
  height: 60px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 15px;
`;

const Button = styled.button`
  border-radius: 15px;
  width: 150px;
  height: 60px;
  outline: none;
  border: none;
  background-color: skyblue;
  font-size: 20px;
  font-weight: 700;
  cursor: pointer;

  &:hover {
    opacity: 0.5;
  }
`;

const UploadButton = styled.label`
  border-radius: 15px;
  width: 150px;
  height: 60px;
  background-color: skyblue;
  font-size: 20px;
  font-weight: 700;
  cursor: pointer;
  display: flex;
  justify-content: center;
  align-items: center;

  &:hover {
    opacity: 0.5;
  }
`;

const MarkDownExample = `
## Hello World
### Happy Hacking
> React Programming
`;

function App() {
  const editorRef = useRef<Editor>(null);

  const onSubmitBtnClick = () => {
    const txt = editorRef.current?.getInstance().getMarkdown();
    alert(txt);
  };

  const onFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    if (e.target.files && e.target.files[0]) {
      const file = e.target.files[0];
      if (file.name.split('.').pop()?.toLowerCase() !== 'md') {
        alert('잘못된 파일 확장자입니다.');
        return;
      }
      const fileReader = new FileReader();
      fileReader.onload = () => {
        if (typeof fileReader.result === 'string') {
          editorRef.current?.getInstance().setMarkdown(fileReader.result, false);
        }
      };
      fileReader.onerror = () => {
        alert('파일을 읽어들이던 도중 에러가 발생하였습니다.');
      };
      fileReader.readAsText(file);
    }
  };

  return (
    <Container>
      <Editor
        previewStyle="vertical"
        height="100%"
        initialValue=" "
        language="ko-KR"
        previewHighlight={false}
        ref={editorRef}
        hideModeSwitch={true}
      />
      <ButtonContainer>
        <UploadButton>
          Upload
          <input type="file" accept=".md" style={{ display: 'none' }} onChange={onFileChange} />
        </UploadButton>
        <Button onClick={onSubmitBtnClick}>Submit</Button>
      </ButtonContainer>
    </Container>
  );
}

export default App;
  • 이전 포스팅의 Toast UI Editor에 파일 업로드 기능을 추가한 코드이다.
  • 기존에는 WYSIWYG 방식을 허용했지만, 파일 업로드 후 마크다운에서 WYSIWYG로 모드 전환을 하게 되면, htmlBlock 부분에서 error가 발생했다. 그래서 마크다운에서 WYSIWYG로 모드 전환을 못하도록 수정해주었다.

3. TIL

(1) Input 태그 속성

  • accept
    • 서버로 업로드할 수 있는 파일의 타입을 명시한다.
    • 하나 이상의 파일 타입일 경우 콤마를 사용하여 구분한다.
    • accept 속성을 유효성 검사 도구로 사용해서는 안되며, 업로드된 파일은 서버에서 검증되어야 한다.
    • 이 속성은 input 요소의 type이 file인 경우에만 사용할 수 있다.

(2) label 태그

  • label 태그는 input 태그의 의미를 정의하기 위한 태그이다.
  • label을 클릭하면 해당 label이 설명하는 입력창이 활성화 또는 체크된다.
  • label 태그의 속성으로 for이 있는데 이곳에 설명(연결)하고 싶은 input 태그의 id 값을 지정해준다.

(3) Blob

  • Blob(Binary Large Object)은 이미지, 사운드, 비디오와 같은 멀티미디어 데이터를 다룰 때 사용할 수 있다.
  • 대개 데이터의 크기(Byte) 및 MIME 타입을 알아내거나, 데이터 송수신을 위한 작은 Blob 객체로 나누는 등의 작업에 사용한다.
  • File 객체도 name과 lastModifiedDate 속성이 존재하는 Blob 객체이다.


참고자료

profile
개발 일지를 작성합니다

0개의 댓글