React access <canvas/> ref of a child component

119 views Asked by At

I'm trying to save canvas as PNG file on the press of a button.

This is my code for now: (this part is working)

  const canvasRef01 = useRef(null);

  const saveAsPng = () => {
    const canvas = canvasRef01.current;
    const dataURI = canvas.toDataURL("image / png");


    const aTag = document.createElement("a");
    aTag.href = dataURI;
    aTag.setAttribute("download", "Code Gallery by 0xLeoDev");
    document.body.appendChild(aTag);
    aTag.click();
    aTag.remove();
  };

  return (
    <canvas ref={canvasRef01} />
    <button onClick={saveAsPng}>save as png</button>
  );

My issue start once i try to implement it with a child component.

<Parent/>   //I need to have my "saveAsPng" function  and <button/> here
<Child/>    //I've my <canvas/> tag inside this child 

The question is how to access (refer to) my canvas data from my parent component to get it's dataUrl?


I've tried to solve it with hook defined as dataURI and setDataURI. With idea of passing it as a props. But this "solution" is looping my canvas.

  const [dataURI, setDataURI] = useState(null);

  useEffect(() => {
    const canvas = canvasRef01.current;

    const dataURI = canvas.toDataURL("image / png");
    // setDataURI(dataURI);

    const context = canvas.getContext("2d");
    const width = canvas.width;
    const height = canvas.height;
    draw(context, canvas, width, height, numOfRec, bacgroundColor);
  }, [draw]);

  return (
    <canvas
      ref={canvasRef01}
      {...props}
    />
  );
1

There are 1 answers

0
adsy On

Define the ref and the saveAsPng method in the parent component instead, then pass the ref to the child component. In order for this to work, your child component must implement forwardRef.

You will also need to pass the saveAsPng method down to that child.

const Parent = () => {
  const canvasRef01 = useRef(null);

  const saveAsPng = () => {
    const canvas = canvasRef01.current;
    const dataURI = canvas.toDataURL("image / png");

    const aTag = document.createElement("a");
    aTag.href = dataURI;
    aTag.setAttribute("download", "Code Gallery by 0xLeoDev");
    document.body.appendChild(aTag);
    aTag.click();
    aTag.remove();
  };

  return (
    <Child ref={canvasRef01} onButtonClick={saveAsPng}/>
  );
}
const Child = React.forwardRef(({ onButtonClick }, ref) => {
  return (
    <>
        <canvas ref={ref} />
        <button onClick={onButtonClick}>save as png</button>
    </>
  );
})