首页 > 解决方案 > useState 加载状态未触发

问题描述

我有一个组件正在接受数据,然后将其设置为 XLSX。我想要做的是,当我单击下载时,我想将加载设置为 true 并显示加载指示或用户可以知道正在工作的东西。在我的代码下载工作,但当我点击按钮加载仍然是假的。为什么?

import "antd/dist/antd.css";
import { Button } from "antd";
import { DownloadOutlined } from "@ant-design/icons";
import * as FileSaver from "file-saver";
import * as XLSX from "xlsx";
import React, {useState} from "react";
import moment from "moment";

const ExportToXlxs = ({ data }) => {
  const [loading, setloading] = useState(false)
  const exportData = () => {
    setloading(true)
    const fileType =
      "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8";
    const fileExtension = ".xlsx";
    let mappedData = [];
    data.map((item) => {
      return mappedData.push({
       //make map
      });
    });
    const ws = XLSX.utils.json_to_sheet(mappedData);
    const wb = { Sheets: { data: ws }, SheetNames: ["data"] };
    const excelBuffer = XLSX.write(wb, { bookType: "xlsx", type: "array" });
    const data = new Blob([excelBuffer], { type: fileType });

    FileSaver.saveAs(data, "file" + fileExtension);
    setloading(false)
  };

  return loading ? <div>loading</div> : (
    <Button
      type="primary"
      style={{
        marginLeft: "50px",
        alignSelf: "center",
      }}
      onClick={exportData}
      icon={<DownloadOutlined />}
    >
      Download
    </Button>
  );
};
export default ExportToXlxs;

标签: reactjs

解决方案


您正在exportData函数中运行异步操作。尝试将其更新为:

const exportData = async () => {
    setloading(true)
    const fileType =
      "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8";
    const fileExtension = ".xlsx";
    let mappedData = [];
    data.map((item) => {
      return mappedData.push({
       //make map
      });
    });
    const ws = await XLSX.utils.json_to_sheet(mappedData);
    const wb = { Sheets: { data: ws }, SheetNames: ["data"] };
    const excelBuffer = await XLSX.write(wb, { bookType: "xlsx", type: "array" });
    const data = new Blob([excelBuffer], { type: fileType });

    await FileSaver.saveAs(data, "file" + fileExtension);
    setloading(false)
};

现在,您的操作将在需要的地方等待,然后其他操作(如setLoading异步运行)。基本上发生的事情是,您的setLoading功能将在彼此之后非常快速地运行,而无需先等待您的文件保存。请参阅@vinayakshahdeo 对您的问题的评论

注意:我添加的某些await关键字可能不是必需的。我对您使用的库不太熟悉。


推荐阅读