One of my first interviews with skilled when preparing for my job hunting, they asked me to explain what was my definition of the virtual DOM in React… In this post, I am going to explain what is my understanding of this mysterious virtual DOM.
DOM
Just to get things straight, DOM stands for Document Object Model and is an abstraction of a structured text. For web developers, this text is an HTML code, and the DOM is simply called HTML DOM. Elements of HTML become nodes in the DOM.
Virtual DOM
The virtual DOM is an abstraction of the HTML DOM. It is lightweight and detached from the browser-specific implementation details. Since the DOM itself was already an abstraction, the virtual DOM is, in fact, an abstraction of an abstraction.
Perhaps it’s better to think of the virtual DOM as React’s local and simplified copy of the HTML DOM.
There is no big difference between the virtual DOM and the “real” DOM. This is why the JSX parts of the React code can almost look like pure HTML:
In most cases, when you have an HTML code and you want to make it a static React component, all you have to do is:
- Return the HTML code using the render function
- Replace class attribute name to className, because class is a reserved word in Javascript.
ReactElement vs ReactComponent
When talking about the virtual DOM, it’s important to see the difference between these two:
React Elements
- A React Element is what gets returned from components. It’s an object that virtually describes the DOM nodes that a component represents.
- With a function component, this element is the object that the function returns.
- With a class component, the element is the object that the component’s render function returns.
- React elements are not what we see in the browser. They are just objects in memory and we can’t change anything about them.
- React elements can have other type properties other than native HTML elements.
We can create an object representation of a DOM node using the createElement
method:
const element = React.createElement(
'div',
{id: 'login-btn'},
'Login'
)
When this is rendered to the DOM (using ReactDOM.render
), we'll have a new DOM node that looks like this:
<div id='login-btn'>Login</div>
React Components
- A React Component is a template. A blueprint. A global definition. This can be either a function or a class (with a render function).
- If react sees a class or a function as the first argument, it will check to see what element it renders, given the corresponding props and will continue to do this until there are no more
createElement
invocations which have a class or a function as their first argument. - When React sees an element with a function or class type, it will consult with that component to know which element it should return, given the corresponding props.
- At the end of this processes, React will have a full object representation of the DOM tree. This whole process is called reconciliation in React and is triggered each time
setState
orReactDOM.render
is called.
- Class-Based Components
Create a Class Component:
import React, { Component } from "react";class ClassComponent extends Component {render() {return <h1>Hello, world</h1>;}}
- Formatting when exporting the component
- ES7 extension provides short-cuts to create class headers in VSCode (`Rce + tab` auto-creates a class)
- allow you to manipulate the life cycle within the object itself
- Binding to `this`
2. Functional Components
import React from "react";const FunctionalComponent = () => {return <h1>Hello, world</h1>;};
- Requires hooks to accomplish similar results as class (e.g., class has component_did_mount)
- The clear difference is the syntax. Just like in their names, a functional component is just a plain JavaScript function that returns JSX. A class component is a JavaScript class that extends React.Component which has a render method.
- ES7 extension provides short-cuts in VSCode (`Rfc + tab` auto-creates a class header)
What makes the difference?
ReactComponents are great, we would love to have plenty of them since they are easy to manage. But they have no access to the virtual DOM — and we would like to do as much as possible there.
Whenever a ReactComponent
is changing the state, we want to make as little changes to the “real” DOM as possible. So this is how React deals with it. The ReactComponent
is converted to the ReactElement
. Now the ReactElement
can be inserted to the virtual DOM, compared and updated fast and easily.
The point is - it’s done faster than it would be in the “regular” DOM.
Summary
A virtual DOM object has the same properties as a real DOM object, but it lacks the real thing’s power to directly change what’s on the screen. Manipulating the DOM is slow. Manipulating the virtual DOM is much faster, because nothing gets drawn onscreen.