본문 바로가기
개발/React

React Handsontable로 csv 편집기 만들기 (5)

by 피로물든딸기 2021. 6. 1.
반응형

프로젝트 전체 링크

 

이전 - (4) Drop한 파일 읽기

현재 - (5) 선택한 경로의 파일 읽기

다음 - (6) csv 파일 파싱하기

 

깃허브에서 코드 확인하기


파일 선택을 누르고, 열기를 누르면 onChange가 이것을 감지할 수 있다.

<input type="file" accept=".csv" onChange={console.log("Hello!")}/>

 

log가 나오는 것이 보인다.

다시 library.js에 handleUpload 함수를 만들고 event 객체에 대한 log를 찍어보자.

 

// library.js

...

export const handleUpload = (e) => {
  console.log(e);
}

 

// FileUpload.js

...

<input type="file" accept=".csv" onChange={(e) => lib.handleUpload(e)}/>

 

결과를 확인하면, Drag & Drop과 비슷한 객체를 확인할 수 있다.

handleOnDrop에서는 e.dataTransfer.files에 file이 있었다면, 여기에서는 e.target.files에 파일 정보가 있다.

 

handleOnDrop처럼 handleUpload에서 FileReader를 이용해 file을 읽고 출력해보자.

// library.js

...

export const handleUpload = (e) => {
  let file = e.target.files[0];
  let fileReader = new FileReader();
  
  fileReader.readAsText(file, "utf-8"); // or euc-kr

  fileReader.onload = function () {
    console.log(fileReader.result); 
  };
}

 

이전 글에서 사용한 test.csv를 경로를 이용해서 불러도 같은 결과가 나오는 것을 알 수 있다.


파일을 불러온 후, 다시 파일 선택을 누른 후에 취소 버튼을 누르면 아래의 에러가 나타난다.

 

 

취소 버튼을 누르면서 fileundefined가 되지만, readAsTextfile을 읽기 때문에 발생한다.

따라서 fileundefined인 경우는 return하는 방어 코드를 추가한다.

export const handleUpload = (e, csvObject) => {
  let file = e.target.files[0];
  let fileReader = new FileReader();
  
  if(file === undefined) return; /* 방어 코드 추가 */
  
  fileReader.readAsText(file, "utf-8"); // or euc-kr

  fileReader.onload = function () {
    //console.log(fileReader.result); 
    parsingCsv(fileReader.result, csvObject);
  };
}

 

최종 코드는 아래를 참고하자.

// library.js
export const handleOnDragLeave = (e, setState) => {
  e.preventDefault();
  setState(false);
  return false;
};

export const handleDragOver = (e, setState) => {
  e.preventDefault();
  setState(true);
  return false;
};

export const handleOnDrop = (e, setState) => {
  e.preventDefault();

  let file = e.dataTransfer.files[0];
  let fileReader = new FileReader();

  fileReader.readAsText(file, "utf-8"); // or euc-kr

  fileReader.onload = function () {
    console.log(fileReader.result); 
    return;
  };

  setState(false);
  return false; 
};

export const handleUpload = (e) => {
  let file = e.target.files[0];
  let fileReader = new FileReader();
  
  if(file === undefined) return; /* 방어 코드 추가 */
    
  fileReader.readAsText(file, "utf-8"); // or euc-kr

  fileReader.onload = function () {
    console.log(fileReader.result); 
  };
}

 

// FileUpload.js
import React, { useState } from "react";
import * as lib from "./library.js";
import "../css/FileUpload.scss";

const FileUpload = () => {
  const [dropFlag, setDropFlag] = useState(false);

  return (
    <div
      id="drag-drop-field"
      className={dropFlag ? "in" : ""}
      onDrop={(e) => lib.handleOnDrop(e, setDropFlag)}
      onDragOver={(e) => lib.handleDragOver(e, setDropFlag)}
      onDragLeave={(e) => lib.handleOnDragLeave(e, setDropFlag)}
    >
      <p>drag & drop</p>
      <input type="file" accept=".csv" onChange={(e) => lib.handleUpload(e)}/>
    </div>
  );
};

export default FileUpload;

 

// App.js
import React from "react";
//import * as lib from "./components/library";
import FileUpload from "./components/FileUpload";

const App = () => {
  return (
    <div>
      <div className="App">
        <FileUpload />
      </div>
    </div>
  );
};

export default App;

이전 - (4) Drop한 파일 읽기

다음 - (6) csv 파일 파싱하기

반응형

댓글