ReactJS doesn’t allow manipulation of the browser DOM, Instead you manipulate the virtual DOM which then result into the browser DOM.
Why Virtual DOM?
The reason for a virtual DOM is to enhance and optimize update to the actual virtual DOM.
document.querySelector to select an HTML tag, and you can modify the tag using properties like
Although DOM manipulation is faster this way, it is still problematic because:
DOM changes cause browser to reloaded. This is inefficient.
Recalculating and rendering layout after manipulation is slow
The virtual DOM is node tree of element and attributes just like the browser DOM. The node tree is created by React’s
render() method from React components in response to change in React’s data model.
When there is a change, the
render() method recreates the entire DOM, resulting to a new virtual representation of the DOM.
This involves a three-step process that optimizes the performance and makes the virtual DOM fast:
- It re-renders to new virtual DOM when there is trigger of change in the UI.
- The difference from the old virtual DOM and the new one will be recalculated to see what has changed.
- The browser is updated from the virtual DOM with what has changed.
Updating the actual DOM with new data from the virtual DOM without reloading the browser is not only efficient but ideal. Although, it may seem like the virtual DOM would/should be slow because of the double render, and diffing to see what has changed. The fact is that rendering the virtual DOM is more efficient than rendering UI in the actual browser DOM.
Virtual DOM Object
First thing to know is that all elements in the virtual DOM are a function of
ReactElement is representation of DOM element in the virtual DOM. This is what is then put in the “actual DOM” of the browser.
To understand how this works, you need follow along with code samples you can modify and test. Download code sample from here. Follow the instructions and open the
reactjsvdom/index.html file in your browser and code editor.
The HTML file is the default template that will show all rendered virtual DOM in the browser. It has a
<div> element to contain the rendered DOM and after it is the
<script> tag pointing to the script source file.
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>React's Virtual DOM</title> <script src="https://unpkg.com/react@16/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script> </head> <body> <div id="root"></div> <script src="./vdom.js"></script> </body> </html>
reactjsvdom/vdom.js in your code editor. This is the react component that the
<script> tag above is pointing to. We will write all react code here.
Now let create an element and add (render) it to the browser DOM. To create an element use the
// Create virtual DOM element const headerTag = React.createElement("h1")
The method creates a virtual DOM of
<h1> header tag that will be turned into browser DOM tree. The
headerTag is an instance of
ReactElement. This is how to create
ReactElements implicitly without using JSX.
The element has only been created, but not rendered to the browser DOM, let do that next.
To render elements created by the
createElement() method, the
render() method is used. The method takes in two arguments:
- The virtual Element to render.
- The HTML tag to mount rendered Virtual DOM (the
rootin the HTML template).
//... // Access HTML tag with id of "app" const mountTag = document.querySelector("#app") // Render headerTag into the DOM tree ReactDOM.render(headerTag, mountTag)
The only time you directly access the browser DOM is when getting the HTML tag to mount rendered
A new html element has been inserted as the child of the
div element in the browser DOM. Nothing is showing on the browser because we only added an empty tag without any text in it. To view the tag, right-click on your browser and click on “inspect” to open the developer tools window. click on “Inspector” if you use Firefox or “Elements” if you use Chrome to inspect the HTML document. Expand the
div tag and you should see the
h1 as a child tag.
Add Text(child) To Tag
We’ve rendered and mounted and empty tag, now we’ll add a child element of text to the
h1 tag. To add a child element the
createElement() method will be updated with other arguments added to it.
createElement() method takes in three arguments in all, namely:
- The DOM element type
- The element
- Children of the element
Let’s walk through this arguments.
- The DOM element type is the HTML tag you want to be mounted in the browser. This will act as a parent element to other element that are mounted under it.
- The element
propsis how react passes arguments or attributes to its component. If we had another component then we could pass in data from it as
propsto the current component. we’re not passing
propsso it’ll be left as
- The children DOM consists of
ReactNode(virtual representation of real DOM nodes) objects:
- An array of
To insert text in the
h1 tag, we’ll pass in string as the third argument in
// Create virtual DOM element const headerTag = React.createElement("h1", null, "Hello World!") //...
We know that the
render() method mount the virtual node tree in the actual browser DOM. But you might not know it also accepts a third callback argument that runs after the DOM is mounted. This can be used to run side-effects after the virtual DOM has mounted.
//... // Render virtual node then run callback ReactDOM.render(headerTag, mountTag, () => alert("Think before reacting!"))
To run side-effects in React use lifecycle methods, or the hook method
useEffect()introduced in version 16.8.
The virtual DOM makes updating the browser with changes in the data model easier than in other UI libraries. This boost performance by optimizing UI. With that said, as a developer, If working with another library other than ReactJS does the job well for you then stick to it. “A tool is only as good as the person using it.”
Thank you for reading 🙏🏿