我有一个react应用程序,它使用Plotly.js在前端动态生成图像。我想添加图像共享功能。为此,我尝试使用反应-份额。社交平台需要图像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)
));
};接收到响应后,将其传递给共享组件,如下所示
<FacebookShareButton
url={imgURI}
>
<FacebookIcon/>
</FacebookShareButton>代码示例不是异步的,因此图像URI不会传递给共享组件,因此共享无法工作。我试图使用条件传递支持,这取决于它是否已经定义,并且没有想出解决方案。我还查找了处理异步urls的一些 问题 在反应-份额回购,但似乎没有一个处理单击时的动态图像共享。
对于如何完成这项任务,我将非常感激。
发布于 2021-11-19 20:27:55
这是一个严重的黑客领域,如果这个公关已经完成,整个事情会简单得多。
但是,下面的代码应该可以工作(请参阅码箱)。
关键步骤是:
openShareDialogOnClick = false)onClick处理程序,该按钮异步获取url并设置状态(触发重新呈现)url支柱中有一个真正的地址),然后将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>
);
}发布于 2021-11-24 14:24:21
如果可能的话,可以使用navigator.share api。
您可以编写一个包装器来管理加载状态并禁用组件的图标。
创建异步共享组件
//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>
);
};现在,使用它作为您的实际响应共享图标的包装器。就像这样
const Share = () => {
const [url, setUrl] = useState()
useEffect(() => {
fetch('/imgUrl').then(getUrlFromRes).then(setUrl)
}, [])
return (
<AsyncShareLoader url={url}>
<FacebookShareButton>
<FacebookIcon />
</FacebookShareButton>
</AsyncShareLoader>
);
}扩展此技术,您可以按Andrew的建议手动窃取单击。
https://stackoverflow.com/questions/69996381
复制相似问题