Представьте, что мы живем в мире без рамок. У вас есть чистый Javascript, и вам нужно создать социальную сеть. Вы начинаете этот амбициозный проект и понимаете, что вам нужна функция «Нравится».

Вы создаете кнопку, которая будет отображаться под каждым постом, и когда пользователь нажимает — она увеличивает количество лайков на один. На стандартном JS это будет выглядеть так: кнопка с обработчиком кликов, которая найдет (document.getElementById(“post-33__likes”) — в качестве примера) HTML-элемент, содержащий определенное количество лайков. и добавит +1.

Довольно просто, правда?

Со временем вы захотите добавить статистику лайков на ту же страницу и диаграмму лайков. Теперь вам нужно изменить обработчик кликов и добавить что-то вроде этого:

• найдите элемент (document.getElementById(“statistics__likes”)) и добавьте некоторые функции для увеличения лайковой статистики по всем вашим сообщениям
• найдите элемент (document.getElementById («лайки-диаграмма»)) и добавьте некоторые функции для обновления диаграммы.

Кодовая база растет, и вам нужно запоминать все части, связанные с лайками, которые требуют обновления, когда кто-то нажимает кнопку «Нравится». Это утомительный ручной процесс. Представьте, что позже вам понадобится расширить функциональность и обновить 10 или 20 фрагментов данных в разных частях вашего приложения. Вам пришла в голову отличная идея: создать состояние, которое запускает перезагрузку приложения при каждом изменении значения, используя window.reload().

Государство выглядит так:

const state = { post-33__likes: 9999, all_likes: 782 311, … }.

Когда пользователь нажимает кнопку «Мне нравится», вам просто нужно увеличить ее и вызвать window.reload(), чтобы обновить все приложение. Как я говорил ранее, вручную все обновить сложно, но теперь, используя состояние, мы перезагружаем страницу и видим обновленные значения без ручного выбора и обновления.

Но такой подход плох для такого сложного приложения.

Почему?

Из-за процессов перекомпоновки и перерисовки браузера. Когда вы меняете, например, размер элемента DOM, браузер запускает процесс перекомпоновки, а когда вы меняете, например, цвет шрифта, браузер запускает перерисовку. процесс перерисовки элемента. Когда мы вызываем window.reload(), мы получаем целое приложение со свежими данными (в нашем случае — лайками), НО мы воссоздаем всю страницу целиком, включая элементы DOM, которые не должны пересоздаваться (например, как и другие публикации, верхний и нижний колонтитулы, навигация и т. д.). Это затратная задача для ЦП, поскольку она вызывает перекомпоновку и перерисовку для каждого элемента DOM.

React решает эту проблему с помощью Virtual DOM. Он создает дерево элементов DOM в виде объектов, представляющих текущее состояние. Когда пользователь нажимает кнопку «Нравится», состояние обновляется, и React перезагружает/воссоздает текущее дерево элементов DOM в объектах формы, создавая новое дерево элементов DOM в виде объектов с обновленным состоянием (лайки). ЭТО СУПЕР СИЛА ВИРТУАЛЬНОГО ДОМА. Уничтожение дерева ОБЪЕКТОВ (не элементов DOM) не требует процессов перекомпоновки и перерисовки, поскольку объекты НЕ являются визуальными элементами.

Поэтому, когда React видит два дерева Virtual DOM — текущее и новое с состоянием обновления, он проверяет разницу, используя алгоритм согласования, и выполняет повторный рендеринг (перекомпоновку и перерисовку) только те элементы DOM, которые изменились в обновленном дереве Virtual DOM. React обновляет ТОЛЬКО те элементы, которые необходимо обновить, сводя к минимуму перекомпоновку и перерисовку.