One of the previous courses involved a first look at changing the DOM when interacting with a page.
This method drastically differs from the one used in the JS: DOM API course. The most important difference has to do with how the state of the screen that's rendered changes.
If you want to manipulate the DOM directly, you need to do the following:
- Remove the elements that have become irrelevant for the next state
- If necessary, change the elements that are present on the screen and must stay in the new one
- Add the new elements to the page point by point
In other words, to move to a new state, you should change the old one. So you have to know about him.
In React, it's very different. After any change and call to setState
React creates a new state and draws all components as if from scratch. It does the rendering from scratch. It doesn't matter what content was on the screen up to that point or what its positioning was. Any change in React causes the application to be re-rendered.
The creators of React call this approach one-way data flow:
- A user action changes the application state via
setState
- React starts the rendering loop. Starting from the component where the state was changed (usually the root component), the data gradually propagates through the props, from the higher level to the deepest components
- The resulting
html
is integrated into the page
Those familiar with the functional approach can see a direct link. React makes the world immutable. The easiest way to implement this behavior is to use mountElement.innerHTML
, which replaces the entire html
after the setState call.
In practice, this approach has a lot of difficulties (see the example implementation in the additional materials). But it allows you to build a library that will work like React in 200 lines.
The main problem with using innerHTML
is related to performance. To say it's slow is an understatement. So the creators of React went another way.
Virtual DOM tree
Previously in the course, we said React renders components, which can be misleading.
Actually, it works like this:
- First, we run a rendering - a call to the render function for the entire component tree
- Then we create a so-called virtual DOM. It is just a JavaScript object with a certain structure that reflects the state of the screen
- After that, React compares the new virtual DOM tree with the old one and builds the difference between them. It is a diff, an object describing the difference between the old and the new state
- Only at this point does it start drawing the new state into the real DOM
By now, it should be clear that React is smarter than it looks. It makes changes to the DOM as efficiently as possible because it knows how to change it:
There is an important conclusion from the above. React controls the actual DOM — all of the descendants of the element into which we render the root component.
You can't modify it from outside the React application. If such a thing happens, React can't function because it has to keep track of the current state of the DOM to make diff calculations. When this happens, React says it's being interfered with.
Many people think that virtual DOM is not an end in itself. It is not quite correct. It is just an efficient way to implement the idea of a one-way data flow. If innerHTML
worked, no one would make a virtual DOM.
Building a JavaSript object is much cheaper than working with the real DOM. But, sometimes, the calculation process takes a long time and slows the application. One of the following lessons will be devoted to this topic.
Are there any more questions? Ask them in the Discussion section.
The Hexlet support team or other students will answer you.
For full access to the course you need a professional subscription.
A professional subscription will give you full access to all Hexlet courses, projects and lifetime access to the theory of lessons learned. You can cancel your subscription at any time.