ReactDOM

Complete Guide to DOM and ReactDOM in ReactJS

December 16, 2022
Victor Yakubu
React.js

The Fastest Way to Build React UI

Convert Figma designs to production-ready React.js code. Build stunning apps and landing pages faster than your peers and competitors.

Introduction

One of the biggest breakthroughs in web development was the ability to create dynamic and interactive web pages, which ushered in the Web 2.0 era. Prior to this time, web developers could only create a static web page. Now we can create highly responsive and engaging web applications, and this is made possible by our ability to manipulate the DOM (and ReactDOM).

The introduction of frameworks like React ensured that we were able to have access to the DOM and make changes to it a lot faster. It’s for this reason that we have ReactDOM, which you will learn extensively about in this article. We’ll go over the DOM and how it works, and how the virtual DOM that React uses makes manipulating the DOM faster than using the real DOM. And finally, we will then proceed to learn about the various ReactDOM methods.

What is DOM

For a better understanding of ReactDOM, we should first go over what DOM is. The Document Object Model, or DOM, is a set of APIs that allow programmes and scripts to access and manipulate the document tree, the DOM sees a web page as a tree of nodes. With these APIs, you can have access to the document tree (tree of nodes), and with that access, you can change or delete the content in that document.

The DOM tree (document tree) consists of a hierarchy of nodes that represent the structure of the document. Each node contains information about the element it represents and may contain child nodes. The root node is the document object, which contains information about the entire document.

<!DOCTYPE html>
<html>

<head>
	<title>DOM Demo</title>
</head>

<body>
	<h1>Hello World!</h1>
	<input type="checkbox">
	<button style="color:red;">Click Me!</button>

	<ul>
		<li>Google</li>
		<li>ChatGPT</li>
		<li>StackOverflow</li>
	</ul>
</body>

</html>

When you load this web page in your browser, it creates a document tree with this structure.

Document Tree

With this information about the Document Object Model, you can use JavaScript or any other language to

  • Change any HTML elements and attributes on the page
  • Change and update CSS styles in the page or a particular section
  • Remove existing HTML elements and attributes
  • Add new HTML elements and attributes
  • Dynamically react to various HTML events on the page
  • Create new HTML events on the fly on the page

Here is a more extensive course on DOM and DOM manipulations

What is a ReactDOM

ReactDOM is used to render components and elements on the web. It is a part of the React library used to create user interfaces and dynamic web applications, as well as reusable and composable components that can be used in different applications.

It is used to interact and manipulate the DOM structure, including the elements and components that are rendered on the page. It’s also used to control the state of the components and elements on the page. ReactDOM also provides developers with access to the DOM APIs.

Virtual DOM vs Real DOM

The Real DOM is the same as the DOM that was explained earlier, but by definition, you can say the Real DOM is the actual object representation of a web page. It is a tree-like structure consisting of nodes, which represent HTML elements. When a user interacts with a web page, the DOM is updated using a scripting language like JavaScript to reflect the changes.

The “virtual DOM,” as the name suggests, is the virtual representation of the “real DOM,” and it’s local to React. Unlike the “real DOM,” anything the state of the application changes (i.e., an update to any element in the web page), that change is first made to the “virtual DOM,” which is then synced to the “real DOM.”

How is it faster than Real DOM?

How the virtual DOM works

Considering the diagram above: Any change made in React is updated in the virtual DOM (A), and when React notices a change in the virtual DOM (A), it compares the virtual DOM to the snapshot of the virtual DOM (B) taken before the change was made to the virtual DOM (A). With this, React is able to know the particular part of the document that was changed. This process is called diffing, and the algorithm that is used for this process is called a diffing algorithm. So now that React knows the particular node that was updated, it proceeds to replace only that node that was updated in the real DOM (C). which overall makes the performance much better as compared to when the DOM is manipulated directly.

Let’s further solidify our understanding of Real DOM and virtual DOM with an example of how they work on the browser using Javascript code.

Real DOM example

Consider the code below in the js file

function setTimer() {
  const element1 = `
  <div>
    <h1>JavaScript DOM manipulation</h1>
    <input type="text" />
    <p>${new Date().toLocaleTimeString()}</p>
  </div>
`;

  document.getElementById('container1').innerHTML = element1;
  );

}

setInterval(setTimer, 1000);

Here is the output and how it updates the whole div container in every 1secs

Real DOM

When you check the browser dev tools, you will notice that every time the time changes, the whole div is re-rendered. You won’t be able to type inside the input area because the whole div containing the “h1, input, and a p tag” will re-render after every 1 second.

Virtual DOM example

Let’s repeat the same example, but this time using React and the ReactDOM library. and see how the DOM is updated when a change is made.

Consider the code below

function setTimer() {
  const element1 = `
  <div>
    <h1>JavaScript DOM manipulation</h1>
    <input type="text" />
    <p>${new Date().toLocaleTimeString()}</p>
  </div>
`;

//   document.getElementById('container1').innerHTML = element1;

  const demo2 = React.createElement(
    'div',
    null,
    React.createElement('h1', null, 'React Virtual DOM'),
    React.createElement(
      'div',
      null,
      React.createElement('input', { type: 'text' })
    ),
    React.createElement('p', null, new Date().toLocaleTimeString())
  );

  ReactDOM.render(demo2, document.getElementById('container2'));
}

setInterval(setTimer, 1000);

Here is the output on the browser, showing that only the p tag is updated every 1 second.

Virtual DOM

From the browser dev tools you can see that whenever the date changes, only the p tag is updated, it does not affect the other elements in the div.

It’s time to talk about the various ReactDOM methods. All codes used for each example are here in the embedded sandbox link below.

Reference Methods

There are various methods available in the React DOM package that are used to create components, manage state, and provide a way to interact with the DOM in your React project. We will be talking about some of them in this section and others in the legacy reference methods section, mainly focusing on their functions and what they do.

createPortal()

One of the features of ReactDOM is the createPortal() method. This method allows you to render a React component outside of the current React tree. This is useful for creating modals, dialogs, and other elements that don’t fit within the normal React tree structure.

The createPortal() method takes two arguments. The first argument is the React element that you want to render outside of the current tree. This can be a React component or a plain HTML element. The second argument is a DOM node. This is the DOM node where you want to render the element.

Syntax:

ReactDOM.createPortal(child, container)

Let’s look at an example of how to use the createPortal() method. Let’s say you want to render a modal dialog outside of the current React tree. First, you need to create a React component for the modal dialog. This could look something like this:

import React, {useState} from 'react'
import ReactDOM from 'react-dom'

export default function Component() {
  const [open, setOpen] = useState(false)
  return (
    <div className="component">
      <button onClick={() => setOpen(true)}>Open Modal</button>
      <Modal isOpen={open} onClose={() => setOpen(false)}>
        Fancy Modal
      </Modal>
    </div>
  )
}

function Modal({ isOpen, onClose, children }) {
  if (!isOpen) return null
  return ReactDOM.createPortal(
    <div className="modal">
      <button onClick={onClose}>Close</button>
      {children}
    </div>,
    document.body
  )
}

Here is the output on the browser

You can also check this article for more examples and deeper dive into createPortal() method

flushSync()

This is one of the ReactDOM methods that you will want to use sparingly because it can affect the performance of your application. The flushSync() ReactDOM method is a powerful function that can be used to synchronously flush a React update. It is a higher-order function that can be used to force a React component to update synchronously without triggering a re-render or causing a race condition. This is useful when you need to ensure that data is up-to-date before you make a decision or when you need to ensure that a component’s state is consistent with its underlying data.

The flushSync() method takes two arguments: a callback and an optional options object. The callback is the code that is executed when the update is triggered. The options object is used to specify options such as whether the update should be asynchronous or synchronous.

Syntax:

flushSync(callback)

Let’s consider an example below. React normally uses automatic batching to group multiple state updates to a single re-renders for better performance, but as explained earlier, there are times when you need to trigger multiple re-render through your state changes, that’s where flushSync() comes in.

import React, {useState} from 'react'
import { flushSync } from 'react-dom'

export default function FlushSync() {
  const [count, setCount] = useState(0);
  const [toggle, setToggle] = useState(false)

  const handleClick = () => {
    flushSync(() => {
      setCount(count => count + 1)
    })
    flushSync(() => {
      setToggle(toggle => !toggle)
    })
  }

  console.log('Rendered', count, toggle)

  return (
    <div className="App">
      <button onClick={handleClick}>Click Me!</button>
      <div>Count: {count}</div>
      <div>Toggle: {toggle.toString()}</div>
    </div>
  )
}

In the example, when the button is clicked, the state first re-renders to update the count value and also re-renders for a second time to update the toggle to either true or false.

Legacy Reference Methods

render()

The render() ReactDOM method is an essential part of React development, and it is used to render React components into an HTML DOM tree. It is called together with the root element of the application, and then it is used to render all the other components into the DOM. By using this method, React developers can have control over how components are displayed and updated in the browser.

When the component is rendered, React will also take care of mounting and unmounting the component. This means that when the component is rendered, React will attach any necessary event handlers, and when the component is unmounted, React will clean up any event handlers that were attached.

Syntax:

ReactDOM.render(element, container, callback)

Command:

import React from 'react';
import ReactDOM from 'react-dom';

// create the component to be rendered
const App = () => {
   return <div>Render Me using the render method!</div>
}

// render App component and show it on screen
ReactDOM.render(<App />, document.getElementById('root'));

As seen above, the render function takes three arguments: the element, which can be a JSX expression; the container where the element will be rendered; and lastly, the callback argument, which is a callback function that will be executed when the render is complete. However, the callback argument is optional.

unmountComponentAtNode()

Unmounting a React component is an important part of the React lifecycle. Unmounting a component means that the component is removed from the DOM and its associated state is destroyed. ReactDOM provides a method for unmounting a component from the DOM called unmountComponentAtNode(). This method could be useful when you need to replace a component with another one. It can also be used to unmount a component when the user goes to a different page in your application.

To unmount a React component, you first need to import the ReactDOM library into your application. Once imported, you can call the unmountComponentAtNode() method with the DOM node of the component you want to unmount as an argument.

unmountComponentAtNode(container)

Once the component is unmounted, its associated state will be destroyed, and it will no longer be rendered in the DOM.

import {render, unmountComponentAtNode} from 'react-dom';

export default function UnMount() {
  const domNode = document.getElementById('demo');

if (domNode) {
  document.getElementById('render').addEventListener('click', () => {
    render(<App />, domNode);
  });
}

if (domNode) {
  document.getElementById('unmount').addEventListener('click', () => {
    unmountComponentAtNode(domNode);
  });
}

const App = () =>{
  return (
    <div>I will be unmounted soon</div>
  )
}

  return (
    <div>
      <div id="demo"></div>
      <button id='render'>Render React App</button>
      <button id='unmount'>Unmount React App</button>
    </div>
  )
}

Start writing or type a slash /

Unmounting a component is an important part of the React lifecycle and should be done when you no longer need the component to be rendered in the DOM.

findDOMNode()

One of the key tools in React is the findDOMNode() method. This method is used to access the underlying DOM node of a React component. The findDOMNode() method is part of the ReactDOM package, which is used to interact with the DOM. It provides a way to access the DOM node of a React component. This method is used in order to interact with the DOM directly or manipulate the DOM in some way.

The findDOMNode() method takes one argument, which is the React component instance. It returns the DOM node of the component instance. The returned DOM node can then be used to access the DOM elements and manipulate them in some way.

Syntax:

ReactDOM.findDOMNode(component)
import React from 'react'
import ReactDOM from 'react-dom'

export default function FindDOMNode() {
  const findDomNodeHandler = () => {
    let myDiv = document.getElementById('myDiv')
    ReactDOM.findDOMNode(myDiv).style.color = "red"
  }
  return (
    <div className="App">
      <div id="myDiv">This is a Demo</div>
      <button onClick={findDomNodeHandler}>Find Dom Node</button>
    </div>
  );
}

From the code above, when you click on the button, it calls the findDomNodeHandler() which changes the text in the div with id=”myDiv” to green. You can find the code here.

Updated Legacy Reference in React 18

With the release of React 18 by the React team, there have been some updates for some ReactDOM methods.

createRoot()

ReactDOM’s createRoot() method is a new addition to the ReactDOM API that allows developers to render React components into a different DOM element than the one provided by the traditional render() method. This method makes it easier to create an application that can be embedded into an existing DOM structure, such as a legacy web page or an existing application.

The createRoot() method accepts a container parameter, which is an HTML DOM element and returns a root ReactDOM component. The root component can then be used with ReactDOM.render() to render React components into the DOM. This makes it easier to mount React components in the DOM without having to manually create a root DOM node.

Syntax:

createRoot(container[, options]);

Here is how to use the createRoot() method

import { StrictMode } from "react";
import { createRoot } from "react-dom/client";

import App from "./App";

const rootElement = document.getElementById("root");
const root = createRoot(rootElement);

root.render(
  <StrictMode>
    <App />
  </StrictMode>
);

One of the main benefits of using createRoot() is that it ensures that the React component tree is rendered within a single root DOM node. This helps to improve performance and makes the code more maintainable as the entire React component tree is contained within a single root DOM node.

root.unmount()

This method replaces the deprecated unmountComponentAtNode() in React 18. The ReactDOM method root.unmount() is a powerful way to clean up and remove a React component from the DOM.

The root.unmount() method is particularly useful when dealing with components that have child components. When a component is unmounted, all of its child components are automatically unmounted as well, allowing for clean and efficient removal of the component from the DOM. This can help to prevent memory leaks and other issues that can arise from components that are not properly removed from the DOM.

You can simply unmount any component by calling the method and passing the component you want to unmount into it.

Syntax:

<component to unmount>.unmount();

Command:

root.unmount();

When using root.unmount(), it is important to ensure that any state associated with the component is also removed. This helps to ensure that any state associated with the component is reset and not carried over to the next component that is rendered.

Frequently Asked Questions related to ReactDOM

What is the difference between React and ReactDOM?

React is a JavaScript library for building user interfaces. ReactDOM is a package that serves as the entry point to the DOM and server renderers for React. ReactDOM is responsible for rendering components to the DOM, while React is responsible for managing the state and components.

Why ReactDOM is used?

ReactDOM is used to render React components into the DOM. It provides an API for DOM manipulation and a way to access the DOM nodes and elements. It is also used to apply React-specific attributes and updates to the DOM elements when the data changes.

Materials on ReactDOM

Here are some materials you can use to further solidify your understanding of the DOM, ReactDOM, and the various ReactDOM methods:

Conclusion

In the course of this article, we have been able to touch on the DOM, explaining with examples how it works and also stating the reason why React introduced the virtual DOM, which is mostly for speed and performance. We also learned about ReactDOM, which is the library that React uses to manipulate the DOM. Last but not least, we discussed the various ReactDOMs and provided examples of how they work.

I hope you found this helpful and that you were able to learn a lot. The CopyCat blog also has more insightful articles and tutorials by our amazing authors; do well to check them out. Here are some of them:

Lastly, CopyCat has an amazing and cool plugin that helps you convert Figma design to React code in a few minutes, thereby reducing your development to production time for you and your team. Check out the CopyCat plugin now.

Related Articles

  • React.js

    Guide to building your ReactJS custom hooks

    Introducing the concept of React custom hooks ReactJS has introduced powerful improvements to web development since its introduction in 2013 as part of the family of UI libraries. This improvement is not only thanks to the introduction of custom hooks, but also…

    August 13, 2022
  • React.js

    Utilize React to the Max With The Top 15 React Component Libraries

    React is without a doubt the best JavaScript frontend library, powering over 10 million websites on the internet. Because React is the most popular UI library, many UI component libraries have been created to help developers in creating visually attractive…

    October 1, 2022

Convert Figma To React

Convert Figma designs to production-ready React.js code. Build stunning apps and landing pages faster than your peers and competitors.

Convert Design to Code