Для чого потрібен тип React.ReactNode?
Що таке React.ReactNode
React.ReactNode - це універсальний тип для будь-якого допустимого вмісту React,
який може бути відрендерений всередині JSX.
Він описує все, що React може "відрисувати" в дереві:
- елементи (
<div />,<Component />), - рядки і числа,
- булеві значення і
null/undefined(нічого не рендерять), - масиви таких же сутностей,
React.Fragment.
1. Формальне визначення (спрощено)
javascript
type ReactNode =
| ReactElement
| string
| number
| boolean
| null
| undefined
| ReactNode[]; // рекурсивноТобто React.ReactNode - це "все, що React може прийняти як дочірній елемент".
2. Де він використовується
1) Для children
Найчастіше застосування:
javascript
type Props = {
children: React.ReactNode;
};
function Card({ children }: Props) {
return <div className="card">{children}</div>;
}Тепер у Card можна передати будь-який JSX:
javascript
<Card>
<h1>Title</h1>
<p>Text</p>
<button>Button</button>
</Card>2) Для контенту, який може бути JSX, рядком або числом
javascript
type Props = {
label: React.ReactNode; // може бути текст, іконка, JSX
};
function Button({ label }: Props) {
return <button>{label}</button>;
}
<Button label="Save" />
<Button label={<SaveIcon />} />
<Button label={42} />3) Для списків і масивів JSX-елементів
javascript
const list: React.ReactNode[] = [
<li key="1">One</li>,
<li key="2">Two</li>,
];3. Відмінність від інших типів
| Тип | Що описує | Приклад використання |
|---|---|---|
React.ReactNode | Будь-який вміст, який React може відрендерити | children, content, label |
React.ReactElement | Тільки один конкретний React-елемент | <div />, <Component /> |
JSX.Element | Те саме, що ReactElement (тип результату JSX) | Значення, яке повертає компонент |
ReactNode[] | Масив вузлів | Списки, фрагменти |
Часто:
- повернення з компонента:
JSX.ElementабоReactElement - пропси-композиції (children):
React.ReactNode
4. Приклади відмінностей
javascript
function A(): JSX.Element {
return <div>Ok</div>; // компонент повертає JSX.Element
}
function B({ children }: { children: React.ReactNode }) {
return <div>{children}</div>; // приймає будь-який вміст
}5. Чому не JSX.Element для children
JSX.Element - занадто вузький тип: він не включає рядки, числа і null.
javascript
// Помилка, якщо використати JSX.Element
function Title({ children }: { children: JSX.Element }) {
return <h1>{children}</h1>;
}
// Правильно
function Title({ children }: { children: React.ReactNode }) {
return <h1>{children}</h1>;
}
<Title>Text</Title>; // string - теж ReactNode6. Коли краще НЕ використовувати ReactNode
- Якщо очікується конкретний тип (наприклад, функція-рендер-проп), краще вказати
() => ReactNode. - Якщо компонент має приймати тільки елемент, а не рядок - використовуйте
ReactElement.
javascript
type Props = {
trigger: React.ReactElement; // очікуємо один JSX-елемент
};Підсумок
| Параметр | React.ReactNode |
|---|---|
| Що описує | Все, що може бути відрендерено в React |
| Включає | елементи, рядки, числа, null, undefined, boolean, масиви |
| Часто використовується для | children, label, content, slot |
| Не включає | функції, об'єкти, проміси (їх не можна напряму рендерити) |
| Альтернатива | ReactElement, JSX.Element - якщо потрібен тільки один елемент |
Коротко:
React.ReactNode- це "все, що React може відрисувати". Використовуй його дляchildrenі будь-яких пропів, де може бути будь-який JSX, текст або число.Якщо ж ти хочеш дозволити тільки один React-елемент, використовуй
ReactElement.
Коротка відповідь
Для співбесідиPremium
Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.