현재 - (7) App.js에서 파싱된 csv 파일 받기
이전 글에서 FileUpload에서 csv를 parsing하였다.
csv를 parsing한 내용은 App.js에서 보여주려고 한다.
parsing한 내용과 csv의 height와 width를 App.js에서 가지고 올 수 있도록 App.js를 아래와 같이 수정하자.
// App.js
import React, { useState } from "react";
//import * as lib from "./components/library";
import FileUpload from "./components/FileUpload";
const csvObjectDefault = {
HEIGHT: 0,
WIDTH: 0,
csv: [],
};
const App = () => {
const [csvObject, setCsvObject] = useState(csvObjectDefault);
return (
<div>
<button onClick={() => console.log(csvObject)}>print csv</button>
<div className="App">
<FileUpload setCsvObject={setCsvObject} />
</div>
</div>
);
};
export default App;
수정된 내용은 아래와 같다.
csvObject에 csv 파일의 정보(height, width, parsing된 내용)를 저장하도록 useState를 이용해 초기화한다.
const csvObjectDefault = {
HEIGHT: 0,
WIDTH: 0,
csv: [],
};
const App = () => {
const [csvObject, setCsvObject] = useState(csvObjectDefault);
...
csvObject가 제대로 들어왔는지 확인하기 위해 button을 추가한 후, onClick에 log를 출력하도록 하자.
<button onClick={() => console.log(csvObject)}>print csv</button>
print csv 버튼을 클릭하면, 초기화 된 내용이 잘 출력된다.
FileUpload component에 props로 setCsvObject를 넘긴다.
<FileUpload setCsvObject={setCsvObject} />
FileUpload.js에는 setCsvObject props를 받도록 수정하면 된다. (destructuring assignment, 비구조화 할당)
// FileUpload.js
...
const FileUpload = ({setCsvObject}) => { ... }
FileUpload에 setCsvObject를 넘겨 받았으므로, handleOnDrop과 handleUpload에도 넘겨주자.
// FileUpload.js
onDrop={(e) => lib.handleOnDrop(e, setDropFlag, setCsvObject)}
<input type="file" accept=".csv" onChange={(e) => lib.handleUpload(e, setCsvObject)}/>
마찬가지로, library에서도 handleOnDrop과 handleUpload에 setCsvObject를 넘겨주고 parsingCsv도 수정한다.
export const handleOnDrop = (e, setState, setCsvObject) => {
...
parsingCsv(fileReader.result, setCsvObject);
...
};
export const handleUpload = (e, setCsvObject) => {
...
parsingCsv(fileReader.result, setCsvObject);
...
}
parsingCsv에서 setCsvObject를 넘겨받는다.
먼저 file을 parsing하기 전에 obj를 []로 초기화한다.
그리고 sptLine을 순회하면서 height를 counting한다.
csvObject의 csv[]의 모든 length는 같으므로, 가장 첫 번째의 length를 width로 한다.
마지막으로 setCsvObject를 이용해 csvObject에 값을 저장한다.
export const parsingCsv = (file, setCsvObject) => {
let height, width;
let obj = {
HEIGHT: 0,
WIDTH: 0,
csv: [],
};
obj.csv = [];
let sptLine = file.split(/\r\n|\n/);
console.log(sptLine);
height = 0;
for(let line of sptLine)
{
if(line === "") continue;
let spt = mySplit(line, DELIMITER, APOSTROPHE);
obj.csv.push(spt);
height++;
}
width = obj.csv[0].length;
obj.HEIGHT = height;
obj.WIDTH = width;
setCsvObject(obj);
return;
}
코드를 수정한 후, file을 upload 한다.
그리고 print csv를 누르면 csv파일에 대한 정보가 App.js의 csvObject에 잘 들어간 것을 확인할 수 있다.
최종 코드는 아래와 같다.
// App.js
import React, { useState } from "react";
//import * as lib from "./components/library";
import FileUpload from "./components/FileUpload";
const csvObjectDefault = {
HEIGHT: 0,
WIDTH: 0,
csv: [],
};
const App = () => {
const [csvObject, setCsvObject] = useState(csvObjectDefault);
return (
<div>
<button onClick={() => console.log(csvObject)}>print csv</button>
<div className="App">
<FileUpload setCsvObject={setCsvObject} />
</div>
</div>
);
};
export default App;
// FileUpload.js
import React, { useState } from "react";
import * as lib from "./library.js";
import "../css/FileUpload.scss";
const FileUpload = ({setCsvObject}) => {
const [dropFlag, setDropFlag] = useState(false);
return (
<div
id="drag-drop-field"
className={dropFlag ? "in" : ""}
onDrop={(e) => lib.handleOnDrop(e, setDropFlag, setCsvObject)}
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, setCsvObject)}/>
</div>
);
};
export default FileUpload;
// library.js
const DELIMITER = ',';
const APOSTROPHE = '"';
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, setCsvObject) => {
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);
parsingCsv(fileReader.result, setCsvObject);
return;
};
setState(false);
return false;
};
export const handleUpload = (e, setCsvObject) => {
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, setCsvObject);
};
}
export const mySplit = (line, delimiter, ignore) => {
let spt = [];
let tmp = "";
let flag = false;
for(let i = 0; i < line.length; i++)
{
if(ignore === line[i] && flag === true)
{
flag = false;
continue;
}
else if(ignore === line[i])
{
flag = true;
continue;
}
if(line[i] === delimiter && flag === false) {
spt.push(tmp);
tmp = "";
continue;
}
tmp += line[i];
}
spt.push(tmp);
return spt;
}
export const parsingCsv = (file, setCsvObject) => {
let height, width;
let obj = {
HEIGHT: 0,
WIDTH: 0,
csv: [],
};
obj.csv = [];
let sptLine = file.split(/\r\n|\n/);
console.log(sptLine);
height = 0;
for(let line of sptLine)
{
if(line === "") continue;
let spt = mySplit(line, DELIMITER, APOSTROPHE);
obj.csv.push(spt);
height++;
}
width = obj.csv[0].length;
obj.HEIGHT = height;
obj.WIDTH = width;
setCsvObject(obj);
return;
}
'개발 > React' 카테고리의 다른 글
React Handsontable로 csv 편집기 만들기 (9) (1) | 2021.06.05 |
---|---|
React Handsontable로 csv 편집기 만들기 (8) (0) | 2021.06.04 |
React Handsontable로 csv 편집기 만들기 (6) (0) | 2021.06.02 |
React Handsontable로 csv 편집기 만들기 (5) (1) | 2021.06.01 |
React Handsontable로 csv 편집기 만들기 (4) (0) | 2021.05.31 |
댓글