PassFront
  1. PassFront
  2. База знаний
  3. Основы React

Зачем библиотека React делится на пакеты ReactDOM и React?

Основы React

Разделение на react и react-dom — это архитектурная граница между «что рендерить» (платформонезависимое ядро) и «куда рендерить» (конкретная платформа).

Мотивация: один React — много платформ

Ядро (пакет react) содержит всё, что не зависит от среды: компоненты, элементы, хуки, контекст (сам reconciler — пакет react-reconciler, который встраивается в каждый рендерер). Рендереры привязывают его к платформам:

  • react-dom — браузерный DOM (плюс react-dom/server для SSR);
  • react-native — нативные iOS/Android-компоненты;
  • кастомные рендереры (react-reconciler): react-three-fiber (3D), ink (терминал), react-pdf...

Логика компонентов и хуков одна и та же везде; меняется только слой отрисовки. Не будь разделения, React Native пришлось бы тащить весь DOM-код, а web — нативный.

Что это даёт на практике

  • Кроссплатформенный код: компоненты без DOM-специфики зависят только от react — их можно шарить между web и native.
  • Изолированная эволюция: ядро и рендереры версионируются и развиваются согласованно, но код чётко разделён; SSR-API живут в react-dom/server и не попадают в клиентский бандл без нужды.
  • Чистота зависимостей: библиотеки хуков/логики зависят только от react и работают с любым рендерером.

Как выглядит граница в коде

import { useState } from 'react';               // ядро: логика
import { createRoot } from 'react-dom/client';  // рендерер: браузер

createRoot(document.getElementById('root')).render(<App />);

Хуки, memo, Context — из react; порталы, createRoot, hydrateRoot, flushSync — из react-dom.

Коротко для собеседования

Деление отделяет платформонезависимое ядро (компоненты, хуки, контекст; дифф выполняет reconciler внутри рендерера) от рендерера конкретной среды (react-dom — браузер). Это позволяет тому же ядру работать в React Native, three-fiber и др., шарить код между платформами и держать SSR/DOM-API отдельно от логики.

Другие вопросы раздела