Коротка відповідь
juniorFragment — це контейнер без додаткового вузла у DOM, що дозволяє групувати елементи. Portal — це спосіб рендерити дочірні компоненти в іншому місці DOM, наприклад модальне вікно. Обидва потрібні для чистого JSX і управління DOM‑структурою.
Повне пояснення
Що це і навіщо
- Fragment (
<></>абоReact.Fragment) дозволяє повернути кілька елементів без додавання зайвого вузла в DOM. Це корисно, коли потрібен список елементів у JSX, але не хочеться створювати зайвий<div>. - Portal (
ReactDOM.createPortal) рендерить дочірній компонент у вказаному елементі DOM, який може бути поза поточним деревом. Це необхідно для модальних вікон, тултіпів, сповіщень тощо, де потрібен контроль над позицією у DOM.
Ключові принципи/терміни
- Fragment: безпечний, не змінює структуру DOM.
- Portal: рендеринг у зовнішньому контейнері, підтримує контекст і пропси.
Як це працює
- Fragment просто обгортає елементи, JSX компілятор розпізнає його як «не рендерити».
- Portal створює новий вузол у DOM і вставляє в нього JSX, при цьому зберігаючи React‑контекст.
Практика і реалізація
// Fragment
return (
<>
<h1>Title</h1>
<p>Description</p>
</>
);
// Portal
const modalRoot = document.getElementById('modal-root');
return ReactDOM.createPortal(
<div className="modal">Content</div>,
modalRoot
);
Тестування
- Для Fragment можна перевірити, що рендер не додає нових вузлів:
expect(container.childNodes.length).toBe(2). - Для Portal використовуйте
@testing-library/reactзcontainer.querySelector('#modal-root').
Особливості в контексті React
- Fragment підтримується у всіх версіях React.
- Portal працює лише в браузерному середовищі; у SSR треба перевіряти наявність
document.
Оптимізація, типові помилки та edge cases
- Не використовуйте Fragment як обгортку для однієї елементи; це зайве.
- Переконайтеся, що контейнер для Portal існує в DOM; інакше React видасть помилку.
- У SSR Portal не рендериться, тому треба умовно перевіряти
typeof window !== 'undefined'.
Часті помилки
ReactDOM.createPortalбез контейнера → помилка.- Вставка Portal у
document.bodyбез стилів → заливається. - Втрата контексту через Portal → використовуйте
React.cloneElementабоContext.Provider. - Перевантаження DOM через занадто багато Portal → обмежуйте кількість одночасно відкритих.
- Неправильний ключ у Fragment → не потрібен, але якщо використовується список, додайте
key. - Відсутність
React.StrictMode→ Portal працює, але без перевірок. - Використання Fragment у функції, що повертає об’єкт → TypeScript помилка.
- Неправильне використання
React.Fragmentу JSX без обгортки → синтаксична помилка.