首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何与react共享动态生成的图像?

如何与react共享动态生成的图像?
EN

Stack Overflow用户
提问于 2021-11-16 21:43:55
回答 2查看 2.5K关注 0票数 4

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

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

因此,在用户单击共享图标后,应该将前端生成的图像保存到后端。

代码语言:javascript
复制
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)
        ));
  };

接收到响应后,将其传递给共享组件,如下所示

代码语言:javascript
复制
<FacebookShareButton
            url={imgURI}
          >
     <FacebookIcon/>
</FacebookShareButton>

代码示例不是异步的,因此图像URI不会传递给共享组件,因此共享无法工作。我试图使用条件传递支持,这取决于它是否已经定义,并且没有想出解决方案。我还查找了处理异步urls的一些 问题 在反应-份额回购,但似乎没有一个处理单击时的动态图像共享。

对于如何完成这项任务,我将非常感激。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-11-19 20:27:55

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

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

关键步骤是:

  1. 有一些状态来跟踪您是否从服务中得到一个url。
  2. 当此状态为“无”时,禁用facebook按钮的默认行为(即openShareDialogOnClick = false)
  3. 向facebook按钮中添加一个onClick处理程序,该按钮异步获取url并设置状态(触发重新呈现)
  4. 使用effect + ref,以便当url设置为真实的内容时,手动调用按钮上的click事件(它现在的url支柱中有一个真正的地址),然后将url重新设置为"none“。
代码语言:javascript
复制
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>
  );
}
票数 1
EN

Stack Overflow用户

发布于 2021-11-24 14:24:21

如果可能的话,可以使用navigator.share api。

您可以编写一个包装器来管理加载状态并禁用组件的图标。

创建异步共享组件

代码语言:javascript
复制
//AsyncShareLoader.jsx
const AsyncShareLoader = ({ url, children }) => {
  const loading = !url;
  return (
    <div style={{ filter: `grayscale(${loading ? "100%" : "0%"}` }}>
      {React.Children.map(children, (child) =>
        React.cloneElement(child, {
          disabled: loading,
          url: loading ? "none" : url,
          openShareDialogOnClick: !loading
        })
      )}
    </div>
  );
};

现在,使用它作为您的实际响应共享图标的包装器。就像这样

代码语言:javascript
复制
const Share = () => {
  const [url, setUrl] = useState()

  useEffect(() => {
    fetch('/imgUrl').then(getUrlFromRes).then(setUrl)
  }, [])

  return (
    <AsyncShareLoader url={url}>
      <FacebookShareButton>
        <FacebookIcon />
      </FacebookShareButton>
    </AsyncShareLoader>    
  );
}

扩展此技术,您可以按Andrew的建议手动窃取单击。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69996381

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档