I have a download dialog that you can click on to download the graphics on my website. Because the graphics are created with HTML Canvas, I cannot simply download an array of image links. I have to contact each of the components and render each of them into a data URI.
On my app component, I have defined a context to keep track of which components should be downloaded.
export const DownloadFlagsContext = React.createContext<any>(null)
const App: React.FunctionComponent = (props) => {
const [downloadFlags, setDownloadFlags] = useState([])
return (
<DownloadFlagsContext.Provider value={{downloadFlags, setDownloadFlags}}>
<DownloadDialog/>
<div className="graphics">
<Graphic id={1}>
<Graphic id={2}>
<Graphic id={3}>
(multiple graphics)
</div>
</DownloadFlagsContext.Provider>
)
}
In my DownloadDialog, I trigger the downloads by setting the downloadFlags to the id's of each of the components that needs to be rendered.
const download = () => {
const newDownloadFlags = [] as any
for (let i = start; i < end; i++) {
newDownloadFlags.push(i)
}
setDownloadFlags(newDownloadFlags)
}
Now in each of the Graphic components, I trigger the download if the downloadFlags was changed and it contains it's id.
const render = () => {
const canvas = document.createElement("canvas")
/* code to render the graphic */
return canvas.toDataURL("image/png")
}
useEffect(() => {
if (downloadFlags.includes(props.id)) {
download("filename", render())
setDownloadFlags(downloadFlags.filter((s: string) => s !== props.id))
}
}, [downloadFlags])
The problem is that this code is triggering
downloads. For example, if I set the download for 6 graphics it will result in downloading 21 images because every time that I change the downloadFlags, all of the components will get re-rendered, with the difference being that it includes one less id. So in total will download 6+5+4+3+2+1 images. Obviously this is very bad if I have a lot of graphics to download.
I would like to prevent the components from re-rendering so that it only downloads the first 6 times.
Also, I do not want to use a server. I want to download the images on the client side.