Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Що робить патерн "Function as Child"?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**Function as Child (FaCC)** - це патерн, при якому `children` компонента - не JSX-елемент, а функція, яку компонент викликає, передаючи їй дані чи логіку. **Ключове:** компонент сам не рендерить UI, а віддає дані назовні, щоб зовнішній код вирішив, що і як відмалювати.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## Визначення > **Function as Child (FaCC)** - це патерн, при якому `children` компонента - **не JSX-елемент, а функція**, > яку компонент викликає, передаючи їй дані чи логіку. Тобто компонент **сам не рендерить UI**, а **робить делегування** - віддає дані назовні, щоб зовнішній код вирішив, *що і як відмалювати*. --- ## Приклад: трекінг позиції курсора ### Звичайний спосіб ```javascript function MouseTracker() { const [pos, setPos] = useState({ x: 0, y: 0 }); return ( <div onMouseMove={(e) => setPos({ x: e.clientX, y: e.clientY })}> <p>Позиція: {pos.x}, {pos.y}</p> </div> ); } ``` > Працює, але UI і логіка **жорстко пов'язані**. --- ### Function as Child ```javascript function Mouse({ children }) { const [pos, setPos] = useState({ x: 0, y: 0 }); return ( <div onMouseMove={(e) => setPos({ x: e.clientX, y: e.clientY })}> {children(pos)} {/* функція-дитина */} </div> ); } // Використовуємо: function App() { return ( <Mouse> {(pos) => ( <p>Позиція курсора: {pos.x}, {pos.y}</p> )} </Mouse> ); } ``` > Тут `<Mouse>` - компонент з логікою, > а `App` вирішує, **що рендерити**, передаючи функцію як `children`. --- ## Що відбувається під капотом 1. Компонент отримує `children` 2. Перевіряє, що це функція 3. Викликає її з якимись даними ```javascript function Provider({ children }) { const data = { user: "Tim", isLoggedIn: true }; return children(data); // викликаємо функцію } ``` > Таким чином, компонент "ділиться" станом назовні, > але **не контролює, як він відображається**. --- ## Реальний приклад: `<DataFetcher>` ```javascript function DataFetcher({ url, children }) { const [data, setData] = useState(null); useEffect(() => { fetch(url) .then((r) => r.json()) .then(setData); }, [url]); return children(data); // функція отримує дані } // Використовуємо <DataFetcher url="/api/user"> {(data) => data ? <p>Привіт, {data.name}!</p> : <p>Завантаження...</p> } </DataFetcher> ``` > Компонент `DataFetcher` відповідає лише за **логіку завантаження** > А зовнішній код вирішує, **як відмалювати дані** --- ## Function as Child vs Render Props Ці два патерни **майже ідентичні**, різниця - **у синтаксисі** й **у назві пропа**, куди передається функція: | Патерн | Як використовується | |---|---| | **Render Props** | `<Component render={(data) => <UI data={data} />} />` | | **Function as Child** | `<Component>{(data) => <UI data={data} />}</Component>` | Обидва роблять одне й те саме: - отримують функцію як аргумент, - викликають її, - рендерять те, що вона повертає. > У React перевагу віддають `children` - > це *більш природний* JSX-синтаксис, ніж окремий проп `render`. --- ## Коли застосовувати Function as Child Добре підходить, коли: - Потрібно **ділитися логікою** (scroll, resize, mouse, fetch, auth) - Компонент - **"поведінковий"**, а не візуальний - Хочеш **інвертувати контроль**: компонент *надає дані*, а *батько вирішує, як їх відмалювати* Не варто застосовувати, якщо: - компонент має бути **простим UI-блоком**, - логіка не потребує гнучкості відображення (тоді краще кастомний хук). --- ## Зв'язок із сучасними хуками Сьогодні замість `Function as Child` часто використовують **кастомні хуки**, які роблять те саме, але без додаткового JSX-рівня: ### Було (FaCC) ```javascript <Mouse>{(pos) => <Cursor pos={pos} />}</Mouse> ``` ### Стало (Hook) ```javascript function CursorTracker() { const pos = useMouse(); return <Cursor pos={pos} />; } ``` > Хуки - це еволюція патернів `Render Props` / `Function as Child`: > вони вирішують те саме завдання - **розділення логіки й представлення**, але простіше. --- ## Підсумок | Що | Опис | |---|---| | Ідея | Передавати функцію в `children`, щоб компонент ділився станом | | Механізм | Компонент викликає `children(data)` | | Мета | Розділити логіку й UI, не нав'язуючи структуру | | Приклад | `<Mouse>{(pos) => <UI pos={pos} />}</Mouse>` | | Сучасна альтернатива | Кастомні хуки | | Застосовується для | Поведінки (scroll, resize, mouse, fetch, auth) | --- > **Головна думка:** > "Function as Child" - це спосіб **зробити компонент джерелом даних**, > не вирішуючи за розробника, *як саме їх відмалювати*. > > Компонент ділиться логікою → батько керує відображенням.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.