react-csv는 주어진 데이터를 csv 파일로 만들어주는 라이브러리입니다.(https://www.npmjs.com/package/react-csv)
array의 array 형태나 object의 array 형태의 데이터 등을 손쉽게 파일로 만들어서 다운로드 받을 수 있게 해줍니다. 그러나, 이 라이브러리의 단점이 있습니다. 데이터가 생성되는 시점에 데이터를 가지고 다운로드 하게 된다는 점입니다.
<CSVLink data={csvData}>Download me</CSVLink>;
이런 방식으로 컴포넌트를 만들고 csvData로 데이터를 집어 넣습니다.
위의 npm 링크를 들어가보면,
import { CSVLink } from "react-csv";
<CSVLink
data={data}
asyncOnClick={true}
onClick={(event, done) => {
axios.post("/spy/user").then(() => {
done(); // REQUIRED to invoke the logic of component
});
}}
>
Download me
</CSVLink>;
이와 같은 방식으로 onClick 시에 post를 한 후에 done 이전에 data값을 업데이트 해주면 될 것처럼 되어 있지만, 실상은 잘 동작하지 않습니다.
이 문제를 해결하기 위해서는 아래와 같은 방법을 사용해야 합니다.(참고: https://stackoverflow.com/questions/53504924/reactjs-download-csv-file-on-button-click)
import React, { useState, useRef } from 'react'
import { Button } from 'react-bootstrap'
import { CSVLink } from 'react-csv'
import api from 'services/api'
const MyComponent = () => {
const [transactionData, setTransactionData] = useState([])
const csvLink = useRef() // setup the ref that we'll use for the hidden CsvLink click once we've updated the data
const getTransactionData = async () => {
// 'api' just wraps axios with some setting specific to our app. the important thing here is that we use .then to capture the table response data, update the state, and then once we exit that operation we're going to click on the csv download link using the ref
await api.post('/api/get_transactions_table', { game_id: gameId })
.then((r) => setTransactionData(r.data))
.catch((e) => console.log(e))
csvLink.current.link.click()
}
// more code here
return (
// a bunch of other code here...
<div>
<Button onClick={getTransactionData}>Download transactions to csv</Button>
<CSVLink
data={transactionData}
filename='transactions.csv'
className='hidden'
ref={csvLink}
target='_blank'
/>
</div>
)
}
이 방법을 요약하자면, Button 에서 async 오퍼레이션을 대신 처리해준 후에 CSVLink의 click()을 호출하는 것입니다. 먼저 getTransactionData를 보면 async로 선언된 함수입니다. 여기서 post를 호출하여 transaction_table 정보를 가져온 후에 가져온 정보를 setTransactionData로 저장을 합니다. await를 사용하여 이 과정이 모두 끝난 후에 csvLink.current.link.click()을 호출하여 setTransactionData를 통해 set된 정보를 csv로 변환시켜 가져옵니다.
'HOW-TO GUIDES' 카테고리의 다른 글
리액트 파이어베이스에서 무한 스크롤하는 방법 (2) | 2021.09.22 |
---|---|
create-react-app + typescript + tailwindcss + eslint 한 번에 설정하는 법 (0) | 2021.08.15 |
ant design에서 여러 개의 input state를 관리하는 방법(in typescript react) (0) | 2021.08.15 |
M1 맥북에서 plantuml 사용하는 방법 (0) | 2021.08.11 |
Context를 제공하는 컴포넌트가 함수형일 때 useContext를 사용하여 context수정하는 방법 (0) | 2021.08.10 |