Skip to main content

Що робить патерн "Render Props"?

Визначення

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-функцію
Не хочеш використовувати HOCRender 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 - це спосіб ділитися поведінкою, а не розміткою. Компонент віддає назовні стан і події, а зовнішній код вирішує, як їх візуалізувати.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.