I am trying to generate the file name using current date time using below code:
getFileName() {
let d = new Date();
let dformat = [this.padLeft(d.getMonth() + 1),
this.padLeft(d.getDate()),
d.getFullYear()].join('') +
'_' +
[this.padLeft(d.getHours()),
this.padLeft(d.getMinutes()),
this.padLeft(d.getSeconds())].join('');
console.log("getCurrentDate : ", dformat);
return "GridWidget_" + dformat + ".csv";
}
render() {
return(
<CSVLink data={data} filename={this.getFileName()} className="btn btn-primary" target="_blank">Export To CSV</CSVLink>);
}
Issue with the above code is like File name is not generated with date time while downloading the file, but the time is taken while the page loads. What I want to do is the filename should generated only when the user clicks the download button.
I know this doesn't make much difference in time but requirement is like should generate it with actual date time. Not able to understand why this is happening.
I am trying to generate the file name using current date time using below code:
getFileName() {
let d = new Date();
let dformat = [this.padLeft(d.getMonth() + 1),
this.padLeft(d.getDate()),
d.getFullYear()].join('') +
'_' +
[this.padLeft(d.getHours()),
this.padLeft(d.getMinutes()),
this.padLeft(d.getSeconds())].join('');
console.log("getCurrentDate : ", dformat);
return "GridWidget_" + dformat + ".csv";
}
render() {
return(
<CSVLink data={data} filename={this.getFileName()} className="btn btn-primary" target="_blank">Export To CSV</CSVLink>);
}
Issue with the above code is like File name is not generated with date time while downloading the file, but the time is taken while the page loads. What I want to do is the filename should generated only when the user clicks the download button.
I know this doesn't make much difference in time but requirement is like should generate it with actual date time. Not able to understand why this is happening.
Share Improve this question edited Feb 7, 2019 at 10:28 Ravindra asked Feb 7, 2019 at 10:18 RavindraRavindra 2103 silver badges13 bronze badges 5-
Can you modify
CSVLink
ponent? or is it from some library? – mehamasum Commented Feb 7, 2019 at 10:23 - It is ponent provided to download the file from library "react-csv" – Ravindra Commented Feb 7, 2019 at 10:24
-
This is happening because
filename
prop is generated whilerender
process, not when a user clicks a link to download. – Ivan Burnaev Commented Feb 7, 2019 at 10:31 - I tried this by passing reference, but the filename does not get the function reference, it throws exception "Failed prop type: Invalid prop filename of type function supplied to CSVLink, expected string" – Ravindra Commented Feb 7, 2019 at 10:49
-
There is no way to do that unless you re-render
CSVLink
ponent every second, – Kyaw Kyaw Soe Commented Feb 7, 2019 at 11:36
3 Answers
Reset to default 2By default you can't do it because filename
props is download
attribute of <a />
tag which is a built-in HTML. and it generate on render.
<a download="10-36-45.csv" target="_blank" href="">Export To CSV</a>
But there is a hack way you can do by using React Refs to modify attribute of <a>
tag.
export default class extends Component {
$CSVLink = React.createRef();
getFileName() {
let d = new Date();
let dformat = `${d.getHours()}-${d.getMinutes()}-${d.getSeconds()}`;
console.log("getCurrentDate : ", dformat);
return "GridWidget_" + dformat + ".csv";
}
render() {
const data = [
{ firstname: "Ahmed", lastname: "Tomi", email: "[email protected]" },
{ firstname: "Raed", lastname: "Labes", email: "[email protected]" },
{ firstname: "Yezzi", lastname: "Min l3b", email: "[email protected]" }
];
return (
<CSVLink
onClick={() => {
this.$CSVLink.current.link.download = this.getFileName();
}}
ref={this.$CSVLink}
data={data}
filename={this.getFileName()}
className="btn btn-primary"
target="_blank"
>
Export To CSV
</CSVLink>
);
}
}
I change getFileName
method since I don't have information about this.padLeft
, getFileName
method will return current date so you can see the second changes.
Your getFileName is being called during rendering, you need to call it when the click happens (i.e. CSVLink's onCLick) method. Luckily they provide a way to write async onClick.
First, set a state named filename
:
state = {
filename: ""
}
Now add a callback to CSVLink with asyncOnClick={true}. This function is supposed to be called before any handling logic. See the docs.
In that onClick, set your state and once that is finished call done()
:
<CSVLink
data={data}
asyncOnClick={true}
filename={this.state.filename}
onClick={(event, done) => {
this.setState({
filename: this.getFileName()
}, () => {
done()
})
}}
>
Download me
</CSVLink>;
This is because you have used filename={this.getFileName()}
which gets called as soon as the ponent renders.
Since you need the filename to be generated on an event that is being handled inside the CSVLink ponent you will have to define this function inside the CSVLink ponent.
Another alternative would be to make the filename prop take a function instead like filename={this.getFileName}
and inside the CSVLink's onClick
handler where it uses the this.props.filename
property you can change it to this.props.filename()
.
PS: react-csv
allows a onClick
prop which can be async so you can keep filename as a state variable and then call setState
in the onClickHandler
before calling done()
. The documentation is detailed here https://www.npmjs./package/react-csv#--onclick-props
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745202834a4616429.html
评论列表(0条)