Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can i use the document object in React?

For an example if we made a App component and we needed to create an element each time a button was clicked:

function App() {
  const handleClick = () => {
    // Code here
  }

  return (
    <div id="app">
      <button onClick={handleClick}>Click here</button>
    </div>
  )
}

Is it ok if i used document.createElement("div") and document.getElementById("app").append() in that case?

function App() {
  const handleClick = () => {
    let div = document.createElement("div")

    div.innerHTML = "Hi!"

    document.getElementById("app").append(div)
  }

  return (
    <div id="app">
      <button onClick={handleClick}>Click here</button>
    </div>
  )
}
like image 852
Random User Avatar asked Apr 28 '26 12:04

Random User


1 Answers

Can you?

You can, but this goes against the idea of React in the first place and is advised against. Updating the DOM this way can cost you performance and even introduce bugs in your code.

The point of React is to handle updating the DOM in a performant way that is cross-browser compatible. In fact, behind the scenes, React is going to create the <div> element and place it in the DOM, but it is going to do so in a less costly and better-managed way by using a virtual representation of the DOM and everything in it. This is not as expensive as directly building, destroying and rebuilding elements on the page, because, for one, not everything on the page needs to be changed each time a user interaction that changes something of the page happens. React will react to parts of the page that have changed and keep parts that have not changed improving the performance on your web app. (See Reactive Updates), This is one of the reasons the React library was built.

React keeps its own internal registry of elements it renders on the page, in the virtual DOM. It updates and tracks them all through their lifecycle on the page. Because of this, it knows which elements to replace, keep or tear down during user interaction. So creating an element by using the document object directly circumvents the creation (and registration) of a representation of the element in the virtual DOM making React unaware of the element - leaving the lifecycle handling of the element to the browser.

The React way

Because of the above, anything that has to do with the UI; including rendering, updating and destroying is best left to React.

The way to build (thanks to JSX and this is an improvement to @yanir's answer) your element is by simply writing out the element where you need it (or storing it in a variable first and using embedded JSX). The innerHTML attribute can be an embedded expression that is computed in the div element. Don't worry, this operation won't cost as much as using the document object to create elements directly. We'll just need a form of state to track how many times the user has clicked and create a plain JavaScript object then use the map() method to create as many <div>s as needed.

function App() { 
  const [items, setItems] = useState([]);

  const handleClick = () => {
      let obj = { value: "Hi!" };
      setItems([...items, obj]);
  };

  return (
    <div id="app">
      <button onClick={handleClick}>Click here</button> 

      {items.map((item, index) => {
        return <div key={index}>{item.value}</div>;
      })}
    </div>
  )
}

If you need to interact with the DOM directly, through the document object for example, as @Kaushik suggested, you can track the element through the use of hooks like useRef(), to get a reference to the object, useId() for unique stable Ids across server and client, useLayoutEffect() to hook into the browser after DOM updates but before it paints and so on. That being said, there are some APIs and attributes that you may need to access from the document object like events, title, URL, and several other attributes. In as much, as these do not mutate the UI, you can use these when needed, while the UI operations are left to React to handle.

like image 81
Chizaram Igolo Avatar answered Apr 30 '26 00:04

Chizaram Igolo