Skip to content

Instantly share code, notes, and snippets.

@iAdramelk
Last active July 14, 2017 15:21
Show Gist options
  • Save iAdramelk/76aabacd956f77c2c472 to your computer and use it in GitHub Desktop.
Save iAdramelk/76aabacd956f77c2c472 to your computer and use it in GitHub Desktop.

А поговорить я хочу сегодня про VirtualDOM.

Вот небольшой JS Bin с илююстрацией того о чем я вчера говорил про HTML-в-JS: https://t.co/30cEuWYd61

Код можно запустить и посмотреть в консоли (браузерной, не JS Bin'овской) что именно отдает рендер и как они комбинируются.

Главное что нужно понимать из этого примера:

  1. Компоненты возвращают объект с описанием какого-то куска HTML.

  2. Никакого HTML до того как вы вызываете ReactDOM.render нету.

  3. ReactDOM.render берет объект который вы дали ему на вход, сравнивает с тем объектом который ему давали в прошлый раз и ищет разницу.

  4. Если ничего не изменилось – в DOM ничего не идет.

  5. Если что-то изменилось – создается патч, который минимальным количеством операций приводит DOM к новому состоянию.

Пока вы делаете все это в браузере и для SPA все хорошо и замечательно, но вот вам понадобилось сделать интернет-магазин.

И вы вспоминаете, а ведь Реакт-то умеет server side render! Давайте возьмем наши любимы компоненты и все Реакте напишем.

Пишете, рендерите, все работает, но есть один маааленкьий нюанс...

На странице интернет-магазина мало динамики. Возможно только счетчик товаров в корзине и попап с похожими товарами.

И вот тут оказывается, что если вы решили счетчик и попап сделать на Реакте, то вам придется на клиент тащить вообще все шаблоны страницы.

Да, даже если почти все шаблоны это dumb components и никогда не поменяются. Почему так?

Смотрим пример, видим один вызов ReactDOM.render и видим что ему на вход приходит корневая точка нашего дерева компонетов.

И чтобы получить diff страницы и сделать патч нам нужно иметь весь кусок дерева между кнопкой "Добавить в корзину" и счетчиком товаров.

Также с попапом, чтобы показать попап сразу внутри body нам нужно иметь все дерево шаблонов между body и кнопкой показа.

К сожалению это делает Реакт совершенно не пригодным для большого класса проектов: Интернет-магазинов, каталогов, справочников, etc.

Можно конечно генерить на выходе просто html, а динамику делать, простите, через jQuery. Но это какое-то извращение.

Все это, как мне кажется, из-за того что в реакте VirtualDOM, шаблоны и логика взаимодействия очень тесно вместе объединены.

Это упрощает работу с ними и упрощает создание SPA, но накладывает большие ограничения на возможности его серверного использования.

Производные от Реакта, такие как Riot или VueJS тоже этому подвержены. Web Components тоже требуют подгрузки кучи всего.

И как в рамках концепции Реакте сделать возможным использования похожих библиотек для классических сайтов мне не очень ясно.

В связи с этим вопос сегодняшний основной. Сталкивались ли вы с таким? Думали как решать? Может видели какие-то варианты решения?

@nin-jin
Copy link

nin-jin commented Jul 14, 2017

Рендерить реакт можно не только в боди же.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment