1

In my App component, I have 2 components Navbar and View. In my Navbar component, I have an ExportButton component which onClick should generate a screenshot of the View component by passing its ref.

App.js

function App() {
  const view = useRef();
  return (
    <div className="App">
      <Navbar takeSnap={view}/>
      <View ref={view}/>
    </div>
  );
}

Navbar.js

const Navbar = ({ takeSnap }) => {
  return (
    <>
      <Lists />
      <ExportButton takeSnap={takeSnap} />
    </>
  );
};

Button.js

const ExportButton = ({ takeSnap }) => {
 function handleClick(takeSnap) {
    domtoimage.toBlob(takeSnap.current, {}).then(function (blob) {
      saveAs(blob, "myImage.png");
    });
  }
   return (
      <Button onClick={() => handleClick(takeSnap)} />
   );
};

I having some trouble passing ref of View to use the library dom-to-image to take a screenshot. The error says "Uncaught (in promise) TypeError: Cannot read property 'cloneNode' of undefined at makeNodeCopy". This might be a quick fix but I'm not sure where I'm going wrong.

1
  • Is View doing any ref forwarding? I'm assuming domtoimage is needing a DOM element, not a component reference. See reactjs.org/docs/forwarding-refs.html Commented May 6, 2020 at 14:37

1 Answer 1

2

You cannot create a ref for a component, a ref can only reference a DOM element. When you do:

<View ref={view}/>

ref is a reserved keyword and it won't be passed down to your View render function.

You can use forwardRef to solve this problem, or simply use a different keyword such as myRef:

<View myRef={view}/>

Then when you render your View, you can assign this ref to the element you want the screenshot from:

<div ref={myRef} ...
Sign up to request clarification or add additional context in comments.

2 Comments

I still get the same error. Can you elaborate more on this please?
In App, you render Navbar before View, therefore Navbar can't access the ref of View. I think you should pass a callback to Navbar, and let Navbar calls App, then in App you can take the snapshot

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.