第一次点击下载图像按钮是下载react.js-next.js中的.html文件

dojqjjoe  于 2023-02-15  发布在  React
关注(0)|答案(1)|浏览(141)

这是我复制的组件:

import Image from "next/image";
import { useState } from "react";
export default function Home() {
  const [downloadURL, setDownloadURL] = useState("");

  const download = async () => {
    const result = await fetch("http://localhost:3000/test.jpg", {
      method: "GET",
      headers: {},
    });
    const blob = await result.blob();
    const url = URL.createObjectURL(blob);
    setDownloadURL(url);
  };

  const handleDownload = async (e) => {
    try {
      await download();
      URL.revokeObjectURL(downloadURL);
    } catch (error) {
      console.error(error);
    }
  };
  return (
    <div className=" bg-gray-500 bg-opacity-75 transition-opacity flex flex-col justify-center  items-center">
      <Image src="/test.jpg" width={500} height={600} className="mb-2 " />
      <button
        onClick={handleDownload}
        type="button"
        className="flex-1 content-center text-center bg-indigo-600 py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
      >
        <a href={downloadURL} download={"test"}>
          Download Image
        </a>
      </button>
    </div>
  );
}

在第一次点击,我下载.html文件,并在下一次点击我得到的图像下载。但我不能找出是什么原因导致第一次点击下载html文件。
reproducible github repo

iqxoj9l9

iqxoj9l91#

这种方法的几个错误:
1.事件冒泡,click事件在<button>的onClick之前由<a>处理。
1.对状态变量的依赖性在单击事件期间更改,您正在尝试更改绑定到状态的<a> href,但状态不会立即更新,它将仅在下一次呈现时更新,但单击事件不会等待(跳过它是通过异步操作完成的事实)。
我的建议:完全删除<a>并使用旧的经典download函数,该函数动态创建<a>并对其执行“click”:

function Home() {
  const download = (filename, content) => {
    var element = document.createElement("a");
    element.setAttribute("href", content);
    element.setAttribute("download", filename);
    element.style.display = "none";
    document.body.appendChild(element);

    element.click();

    document.body.removeChild(element);
  };

  const handleDownload = async (e) => {
    try {
      const result = await fetch("assets/test.png", {
        method: "GET",
        headers: {}
      });
      const blob = await result.blob();
      const url = URL.createObjectURL(blob);
      download("test", url);
      URL.revokeObjectURL(url);
    } catch (error) {
      console.error(error);
    }
  };
  return (
    <div>
      <img src="/assets/test.png" width={100} height={100} />
      <button onClick={handleDownload} type="button">
        Download Image
      </button>
    </div>
  );
}

抱歉,简化了你的代码。

相关问题