Async CSV Download
Why?
Sometimes you want to download a CSV file for all the data, but you might have paginated the view so you can't just download the data you're currently showing.
In that case, you can use the AsyncCsvDownload component to download the data asynchronously.
How?
Here's the code:
const AsyncCsvDownload = (props) => {
const { children, disabled, filename, fetchData, headers } = props
const [downloadLoading, setDownloadLoading] = useState(false)
const [data, setData] = useState([])
const csvLink = useRef(null)
const dataFunction = async () => {
const csvdata = await fetchData()
console.log(
'csvdata',
csvdata.filter((row) => row)
)
setData(csvdata.filter((row) => row))
csvLink.current.link.click()
setDownloadLoading(false)
}
useEffect(() => {
if (downloadLoading) {
dataFunction()
}
}, [downloadLoading])
return (
<>
{React.cloneElement(children, {
onClick: () => setDownloadLoading(true),
loading: downloadLoading,
disabled,
})}
<CSVLink
data={data}
headers={headers || null}
filename={filename || 'export.csv'}
className="hidden"
ref={csvLink}
target="_blank"
/>
</>
)
}
It clones the children that are passed into the component, and adds an onClick handler to it. When the button is clicked, it sets the downloadLoading state to true.
There's a hidden CSV link that is then auto-clicked when the data is ready (so the browser doesn't block the download).
