Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Що робить патерн "Render Props"?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**Render Props** - це **патерн**, при якому компонент отримує **функцію як пропс** і **викликає її всередині себе**, передаючи потрібні дані чи поведінку. **Ключове:** компонент сам не знає, що саме рендерити - він лише ділиться логікою, а зовнішній код вирішує, як це відобразити.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## Визначення > **Render Props** - це **патерн**, при якому компонент отримує **функцію як пропс**, > і **викликає її всередині себе**, передаючи потрібні дані чи поведінку. Іншими словами: > Компонент сам не знає, *що саме рендерити* - > він просто **ділиться логікою**, а зовнішній код вирішує, **як це відобразити**. --- ## Сенс патерна Render Props дозволяє зробити **логіку, придатну для повторного використання** (наприклад, обробку стану, подій, API-запитів тощо) і **винести її в окремий компонент**, не прив'язуючись жорстко до UI. --- ## Приклад: відстеження позиції курсора ### Без Render Props (усе в одному компоненті) ```javascript function MouseTracker() { const [pos, setPos] = useState({ x: 0, y: 0 }); return ( <div onMouseMove={(e) => setPos({ x: e.clientX, y: e.clientY })} style={{ height: 200, background: '#eee' }} > <p>Координати: {pos.x}, {pos.y}</p> </div> ); } ``` > Працює, але UI і логіка **пов'язані**. > Ми не можемо перевикористати "логіку трекінгу миші" в іншому місці. --- ### З Render Props ```javascript function Mouse({ children }) { const [pos, setPos] = useState({ x: 0, y: 0 }); return ( <div onMouseMove={(e) => setPos({ x: e.clientX, y: e.clientY })} style={{ height: 200 }} > {children(pos)} {/* ← функція-рендер */} </div> ); } // Використовуємо function App() { return ( <Mouse> {(pos) => <p>Позиція курсора: {pos.x}, {pos.y}</p>} </Mouse> ); } ``` > Тут `<Mouse>` **керує логікою**, > а компонент, що його використовує, **сам вирішує, як відрисувати результат**. --- ## Як це працює під капотом - Компонент отримує **функцію через props** (наприклад, `children` або `render`) - Всередині компонента ця функція викликається з потрібними даними - React рендерить те, що поверне ця функція ```javascript {props.render(data)} ``` або ```javascript {props.children(state)} ``` --- ## Приклад: компонент з Render Props для стану ```javascript function Toggle({ children }) { const [on, setOn] = useState(false); const toggle = () => setOn(!on); return children({ on, toggle }); } // Використовуємо <Toggle> {({ on, toggle }) => ( <div> <button onClick={toggle}>{on ? "Викл" : "Увімк"}</button> {on && <p>Секретний текст</p>} </div> )} </Toggle> ``` > Тут `<Toggle>` відповідає за логіку, > а розмітку визначає користувач через **render prop**. --- ## Навіщо потрібен Render Props | Проблема | Як вирішує Render Props | |---|---| | Хочеш **перевикористати логіку**, але не UI | Виносиш її в компонент, а UI передаєш функцією | | Потрібно **розділити дані і представлення** | Дані приходять через render-функцію | | Не хочеш використовувати HOC | Render Props - альтернатива HOC | | Потрібен **компонент, що "ділиться станом"** | Передає state і actions у функцію | --- ## Коли використовувати Підходить для: - логіки, що повторюється (hover, toggle, fetch, resize, mouse position, scroll) - стану (відкрито/закрито, вибрано/не вибрано) - загальних "поведінкових" компонентів Не підходить, якщо: - код стає сильно вкладеним; - достатньо просто винести логіку в **кастомний хук** (в епоху React Hooks). --- ## Сучасна альтернатива Render Props - хуки З появою **React Hooks** патерн Render Props майже повністю замінили **кастомні хуки**, оскільки вони простіші і менш вкладені. ### Приклад: той самий `Toggle`, але з хуком ```javascript function useToggle(initial = false) { const [on, setOn] = useState(initial); const toggle = () => setOn(!on); return { on, toggle }; } function App() { const { on, toggle } = useToggle(); return ( <> <button onClick={toggle}>{on ? "ON" : "OFF"}</button> {on && <p>Секретний текст</p>} </> ); } ``` > Хук робить те саме, що раніше робив компонент з Render Props, > але без вкладеності і з чистішою структурою. --- ## Підсумок | Що | Опис | |---|---| | Ідея | Компонент приймає функцію, яку викликає для рендеру | | Мета | Розділити логіку і представлення | | Як працює | `props.children(state)` або `props.render(data)` | | Переваги | Перевикористовуваність логіки, гнучкість UI | | Сучасна альтернатива | Кастомні хуки | --- > **Головна думка:** > Render Props - це спосіб **ділитися поведінкою, а не розміткою**. > Компонент віддає назовні стан і події, > а зовнішній код вирішує, *як їх візуалізувати*.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.