admin管理员组文章数量:1356597
Using the react-csv
package, I am loading data asynchronously and then trying to download the retrieved data from the server with one click. The problem I am currently facing is that the click is a step behind the current state. When the ponent first renders it downloads an empty CSV file and on the second click it downloads the data from the previous fetch, not the current/latest fetch. That is the same situation that is described here, but the solution mentioned there didn't work in my case.
Here is the code I'm working on:
const [newData, setNewData] = useState([]);
const csvLink = React.createRef();
const csvExport = (
<div>
<Button className="pull-right title-button" onClick={getData}>
CSV Export
</Button>
<CSVLink data={newData} headers={headers} target="_blank" ref={csvLink}></CSVLink>
</div>
);
const getData = async () => {
await getRetailLinkOutes(auth, startDate, endDate, 0, 0, filters, sort, sortDirection, false).then((response) => {
setNewData(response.records);
csvLink.current.link.click();
});
};
Using the react-csv
package, I am loading data asynchronously and then trying to download the retrieved data from the server with one click. The problem I am currently facing is that the click is a step behind the current state. When the ponent first renders it downloads an empty CSV file and on the second click it downloads the data from the previous fetch, not the current/latest fetch. That is the same situation that is described here, but the solution mentioned there didn't work in my case.
Here is the code I'm working on:
const [newData, setNewData] = useState([]);
const csvLink = React.createRef();
const csvExport = (
<div>
<Button className="pull-right title-button" onClick={getData}>
CSV Export
</Button>
<CSVLink data={newData} headers={headers} target="_blank" ref={csvLink}></CSVLink>
</div>
);
const getData = async () => {
await getRetailLinkOutes(auth, startDate, endDate, 0, 0, filters, sort, sortDirection, false).then((response) => {
setNewData(response.records);
csvLink.current.link.click();
});
};
Share
Improve this question
edited Nov 23, 2024 at 8:48
Sadra Saderi
3944 silver badges12 bronze badges
asked Nov 13, 2020 at 8:21
Ferhi MalekFerhi Malek
5147 silver badges15 bronze badges
2
- Were you able to resolve this? Having the same issue, where the data is one step behind the current state and it takes two clicks to download the correct data – N.A Commented Feb 14, 2021 at 22:41
- 2 Update: I resolved my issue by putting the csvLink.current.link.click(); inside a useEffect hook that checks if the data is not null, and also wrapping it in a setTimeout. Referenced here: github./react-csv/react-csv/issues/72 – N.A Commented Feb 14, 2021 at 23:47
2 Answers
Reset to default 5Had the same issue, resolved it by not using <CSVLink asyncOnClick>
(which was a nightmare with Typescript and flat out didn't work unless the user clicked the button twice or unless data was prefetched)
To handle fetching asynchronous data, you can use a normal button to initiate the async fetch and a conditionally rendered button that downloads the CSV
const [initiateDownload, setInitiateDownload] = useState(false)
const [csvRows, setCsvRows] = useState([])
const fetchCsvData = async () => {
const response = await fetchData()
setCsvRows(response.data)
}
useEffect(() => {
if (csvRows.length) {
setInitiateDownload(true)
}
}, [csvRows])
useEffect(() => {
// Enables user to download data more than once
if (initiateDownload) {
setInitiateDownload(false)
}
}, [initiateDownload])
return (
<button onClick={fetchCsvData}>Export CSV</button>
{initiateDownload && (
<CSVDownload
data={csvRows}
headers={csvHeaders}
target="_blank"
/>
)}
)
Elaborating more on what N.A mentioned in the ments:
const [data, setData] = useState([])
const [headers, setHeaders] = useState([])
const excelRef = useRef()
The function to fecth data :
function requestAllHistory () {
console.log('requesting excel history')
requestAllHistoryForExcel(function (response, error) {
// data and headers fetched
setData(data)
setHeaders(headers)
})
}
Inside useEffect
useEffect(() => {
if (headers.length > 0) {
console.log('ExportExcel useEffect', headers)
excelRef.current.link.click()
}
}, [headers])
The CSVLink should not be displayed on the UI (display:'none')
return (
<span>
<button
type='button'
className='btn btn-lg btn-dark'
onClick={() => requestAllHistory()}
>
<span> Export to Excel </span>
<span className='download'></span>
</button>
<CSVLink
data={data}
headers={headers}
filename={filename}
ref={excelRef}
className='hiddenExcel'
target='_blank'
></CSVLink>
</span>
)
本文标签:
版权声明:本文标题:javascript - Loading data asynchronously and downloading CSV data with a click is one step behind the latest retrieved data - St 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744047411a2581786.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论