如何在 react 中下载时在当前日期时间生成文件名



我正在尝试使用以下代码使用当前日期时间生成文件名:

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>);
    }

上述代码的问题就像下载文件时文件名没有生成日期时间,而是在页面加载时花费时间。我想做的是文件名应该只在用户单击下载按钮时生成。

我知道这在时间上没有太大区别,但要求就像应该用实际日期时间生成它一样。无法理解为什么会发生这种情况。

默认情况下,您无法执行此操作filename因为 props 是 <a /> 标签的download属性,该标签是内置 HTML。 并在渲染时生成。

<a download="10-36-45.csv" target="_blank" href="">Export To CSV</a>

但是有一种黑客方法,你可以通过使用 React Refs 来修改<a>标签的属性。

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: "ah@smthing.co.com" },
      { firstname: "Raed", lastname: "Labes", email: "rl@smthing.co.com" },
      { firstname: "Yezzi", lastname: "Min l3b", email: "ymin@cocococo.com" }
    ];
    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>
    );
  }
}

我更改了getFileName方法,因为我没有关于this.padLeft的信息getFileName方法将返回当前日期,以便您可以看到第二次更改。

你的getFileName在渲染过程中被调用,你需要在点击发生时调用它(即CSVLink的onCLick(方法。幸运的是,它们提供了一种在单击时异步编写的方法。

首先,设置一个名为 filename 的状态:

state = {
  filename: ""
}

现在使用 asyncOnClick={true} 向 CSVLink 添加一个回调。这个函数应该在任何处理逻辑之前调用。请参阅文档。

在该onClick中,设置您的状态,一旦完成,请调用done()

<CSVLink
  data={data}
  asyncOnClick={true}
  filename={this.state.filename}
  onClick={(event, done) => {
    this.setState({
      filename: this.getFileName()
    }, () => {
      done()
    })
  }}
>
  Download me
</CSVLink>;

这是因为您使用了filename={this.getFileName()}一旦组件呈现就会被调用。

由于您需要在 CSVLink 组件内处理的事件上生成文件名,因此必须在 CSVLink 组件中定义此函数。

另一种选择是让文件名 prop 采用一个函数,例如 filename={this.getFileName} 并在 CSVLink 的 onClick 处理程序中使用 this.props.filename 属性,您可以将其更改为 this.props.filename()

PS:react-csv允许一个可以异步的onClick道具,因此您可以将文件名保留为状态变量,然后在调用done()之前在onClickHandler中调用setState。此处详细介绍了文档 https://www.npmjs.com/package/react-csv#--onclick-props

最新更新