How to implement document.getElementById in Gatsby(React)

Solution 1:

In Gatsby (like any React project) you can use document.getElementbyId function or other DOM functions. However, it's considered bad practice since you are creating a virtual DOM to avoid access to the real DOM due to the huge impact of performance (like jQuery has for instance).

Of course, you are able to use them, but in Gatsby in particular, since it's prerendering your project and functions/logic before some global objects are created, it may cause severe issues. Most of that issues are explained in Debugging HTML Builds (from Gatsby's official documentation). In other words, window or document may not be created at the moment your function is requesting them.

You can avoid those issues by using a React lifecycle (componentDidMount or useEffect hook) because they wait until the DOM tree is generated to be triggered.

Answering your question; if you want to avoid the usage of a high-impact DOM function, you should use React's ref.

const Post= ({ data }) => {
  const postReference = useRef(null),

  return <Layout>
      <div ref={postReference} dangerouslySetInnerHTML={{ __html: post.html }} />
};

In this dummy example, postReference.current will have exactly the same information as document.getElementById(postId). And it has a low performance impact.

If you still want to use document.getElementById function, you should do something like:

const Post= ({ data }) => {
  useEffect(()=>{
   console.log(document.getElementById("myPost"))
  }, []):

  return <Layout>
      <div id="myPost" dangerouslySetInnerHTML={{ __html: post.html }} />
};

References: https://reactjs.org/docs/refs-and-the-dom.html

When I try to do it in the normal javascript way, I get a warning that says my variable is assigned a value, but it's never used. Any way to fix this?

You can ignore those warnings, but I would suggest to don't do it, if you are not using a variable, remove it to improve your code performance. They appear due to ESLint configuration. To remove it you just need to find .eslintrc.json in your root folder and remove this line: "no-unused-vars": "warn".

Solution 2:

There's a super-dirty hack that can help you if you need to get it working fast:

const docRef = typeof document !== `undefined` ? document : undefined;
if (!docRef) { return };