Render Props — это паттерн в разработке компонентов, позволяющий передавать функцию в качестве свойства, которая управляет тем, как компонент будет визуализирован. В контексте Preact этот подход особенно полезен для создания высоко переиспользуемых и композиционно гибких компонентов.
Вместо того чтобы компонент жёстко определял свой UI, он делегирует часть ответственности вызывающему коду через функцию. Эта функция, получая внутреннее состояние компонента или данные, возвращает элементы JSX.
Пример простого компонента с render prop:
import { h, Component } from 'preact';
class MouseTracker extends Component {
state = { x: 0, y: 0 };
handleMouseMove = (event) => {
this.setState({ x: event.clientX, y: event.clientY });
};
render() {
return (
<div onMouseM ove={this.handleMouseMove} style={{ height: '100vh' }}>
{this.props.render(this.state)}
</div>
);
}
}
// Использование:
<MouseTracker render={({ x, y }) => (
<p>Координаты мыши: {x}, {y}</p>
)} />
Ключевые моменты:
render — это функция, переданная как проп.MouseTracker не знает, как именно будут
отображаться данные, он лишь предоставляет их через
state.Функция в качестве дочернего элемента (children)
является альтернативой render props. Она полностью идентична
концептуально, но синтаксически выглядит более лаконично:
<MouseTracker>
{({ x, y }) => <p>Координаты мыши: {x}, {y}</p>}
</MouseTracker>
Внутри компонента MouseTracker нужно просто рендерить
this.props.children:
render() {
return (
<div onMouseM ove={this.handleMouseMove} style={{ height: '100vh' }}>
{this.props.children(this.state)}
</div>
);
}
Преимущества Function as Children:
render.С приходом Preact Hooks использование Render Props стало ещё гибче. Пример функционального компонента с хуком:
import { h } from 'preact';
import { useState, useEffect } from 'preact/hooks';
function MouseTracker({ children }) {
const [coords, setCoords] = useState({ x: 0, y: 0 });
const handleMouseMove = (event) => {
setCoords({ x: event.clientX, y: event.clientY });
};
useEffect(() => {
window.addEventListener('mousemove', handleMouseMove);
return () => window.removeEventListener('mousemove', handleMouseMove);
}, []);
return children(coords);
}
// Использование:
<MouseTracker>
{({ x, y }) => <p>Координаты мыши: {x}, {y}</p>}
</MouseTracker>
Особенности при использовании хуков:
useEffect) и
состоянием (useState).useReducer или useContext.| Параметр | Render Props | Function as Children |
|---|---|---|
| Синтаксис | Передача функции через проп render |
Передача функции как дочернего элемента |
| Читаемость | Немного громоздкий | Более лаконичный и современный |
| Совместимость | Подходит для классовых и функциональных компонентов | Обычно используется с функциональными компонентами |
| Гибкость | Можно использовать несколько render props | Обычно одна функция children, что упрощает структуру |
Render Props и Function as Children обеспечивают мощный инструмент для композиции компонентов в Preact. Они позволяют изолировать логику от представления, улучшить переиспользуемость и создавать гибкие, динамические интерфейсы без дублирования кода. В функциональных компонентах с хуками этот паттерн становится естественным и удобным способом управления состоянием и побочными эффектами.