如何通过react-share共享react动态生成的图像?

Pol*_*off 7 javascript image reactjs plotly.js react-share

我有一个 React 应用程序,它使用Plotly.js在前端动态生成图像。我想添加图像共享功能。我正在尝试为此使用react-share 。社交平台需要图像 URL 才能进行图像共享,并且不支持 base64 编码等图像。后端的实现可以接收 Base64 格式的图像,存储在数据库中并返回图像的 URL,然后用于与react-share.

由于图像是动态生成的(例如,每次用户调整图表大小时图像都会发生变化),因此当用户单击共享图标时,一切都应该完成。

因此,当用户点击共享图标后,前端生成的图像应该保存到后端

let imgURI;

  const handleClick = () => {
    Plotly.toImage('chartContainer', {
      format: 'png',
      width: 1000,
      height: 600
    })
      .then(dataUrl => api.post('/image/base64ToPng', { image: dataUrl })
        .then(
          (response) => {
            imgURI = response.data.imgURI;
          },
          failure => console.error(failure)
        ));
  };
Run Code Online (Sandbox Code Playgroud)

收到响应后,像这样传递给共享组件

<FacebookShareButton
            url={imgURI}
          >
     <FacebookIcon/>
</FacebookShareButton>
Run Code Online (Sandbox Code Playgroud)

代码示例不是异步的,因此图像 URI 不会传递到共享组件,因此共享不起作用。我尝试根据是否定义来使用条件传递该道具,但没有提出解决方案。我还在react-share repo中查找了一些 处理异步url的问题,但似乎它们都没有处理点击时的动态图像共享。

我非常感谢有关如何完成此任务的提示。

And*_*ier 2

这是一个严重的黑客领域,如果这个 PR已经完成,整个事情就会简单得多。

但是,下面的代码应该可以工作(请参阅codesandbox)。

关键步骤是:

  1. 有一些状态可以跟踪您是否有来自服务的 URL。
  2. 当此状态为“none”时,禁用 facebook 按钮的默认行为(即openShareDialogOnClick= false
  3. 向 facebook 按钮添加一个onClick处理程序,异步获取 url 并设置状态(触发重新渲染)
  4. 使用effect + ref,这样当url设置为真实的东西时,您可以手动调用按钮上的点击事件(现在其urlprop中有一个真实的地址),然后将url重新设置为“none”
import { useEffect, useRef, useState } from "react";
import { FacebookIcon, FacebookShareButton } from "react-share";

async function getUrFromService(): Promise<string> {
  // The real implementation would make a network call here.
  await new Promise((resolve) => setTimeout(resolve, 1000));
  return "https://via.placeholder.com/150";
}

export default function App() {
  const shareButton = useRef<HTMLButtonElement>(null);
  const [url, setUrl] = useState<string>("none"); // Unfortunately, we have to have a dummy string here, or FacebookShareButton will blow up.

  // Provide an onClick handler that asyncronously fetches the url and sets it in the state.
  const onClick = async () => {
    // Be sure to check for the "none" state, so we don't trigger an infinite loop.
    if (url === "none") {
      const newUrl = await getUrFromService();
      setUrl(newUrl);
    }
  };

  // Whenever "url" changes and we re-render, we manually fire the click event on the button, and then re-set the url.
  useEffect(() => {
    if (url !== "none") {
      shareButton.current?.click();
      setUrl("none");
    }
  }, [url, shareButton]);

  return (
    <FacebookShareButton
      ref={shareButton}
      // Disable calling the dialog if we don't have a url yet.
      openShareDialogOnClick={url !== "none"}
      url={url}
      onClick={onClick}
    >
      <FacebookIcon />
    </FacebookShareButton>
  );
}

Run Code Online (Sandbox Code Playgroud)