Концепция Render Props предполагает передачу функции через пропс, которая отвечает за рендеринг части UI. Этот подход позволяет компонентам делиться логикой состояния или поведения без дублирования кода.
import { Component } from 'inferno';
class MouseTracker extends Component {
constructor(props) {
super(props);
this.state = { x: 0, y: 0 };
this.handleMouseMove = this.handleMouseMove.bind(this);
}
handleMouseMove(event) {
this.setState({
x: event.clientX,
y: event.clientY
});
}
render() {
return (
<div style={{ height: '100vh' }} onMouseM ove={this.handleMouseMove}>
{this.props.render(this.state)}
</div>
);
}
}
// Использование
const App = () => (
<MouseTracker render={({ x, y }) => (
<h1>Координаты мыши: {x}, {y}</h1>
)} />
);
Ключевые моменты:
this.props.render — функция, передаваемая извне,
которая возвращает JSX.Преимущества Render Props:
Недостатки:
Higher-Order Component — это функция, которая принимает компонент и возвращает новый компонент с расширенной функциональностью. HOC используется для повторного использования логики между разными компонентами.
import { Component } from 'inferno';
// HOC для отслеживания размера окна
function withWindowSize(WrappedComponent) {
return class extends Component {
constructor(props) {
super(props);
this.state = { width: window.innerWidth, height: window.innerHeight };
this.handleResize = this.handleResize.bind(this);
}
componentDidMount() {
window.addEventListener('resize', this.handleResize);
}
componentWillUnmount() {
window.removeEventListener('resize', this.handleResize);
}
handleResize() {
this.setState({ width: window.innerWidth, height: window.innerHeight });
}
render() {
return <WrappedComponent {...this.props} windowSize={this.state} />;
}
};
}
// Использование
class DisplaySize extends Component {
render() {
const { width, height } = this.props.windowSize;
return <div>Ширина: {width}, Высота: {height}</div>;
}
}
const EnhancedDisplaySize = withWindowSize(DisplaySize);
Ключевые моменты:
Преимущества HOC:
Недостатки:
| Особенность | Render Props | Higher-Order Component |
|---|---|---|
| Передача состояния | Через функцию render |
Через props нового компонента |
| Чистота исходного компонента | Сохраняется | Сохраняется |
| Сложность структуры | Может увеличиваться при вложенности | Глубокие деревья обёрток |
| Использование | Для динамического рендеринга | Для расширения функциональности |
| Комбинирование | Легко комбинируются | Требует аккуратного составления |
Можно создавать HOC, которые принимают render props для дополнительного кастомного рендеринга:
function withMouseTracker(WrappedComponent) {
return class extends Component {
constructor(props) {
super(props);
this.state = { x: 0, y: 0 };
this.handleMouseMove = this.handleMouseMove.bind(this);
}
handleMouseMove(event) {
this.setState({ x: event.clientX, y: event.clientY });
}
render() {
return (
<div onMouseM ove={this.handleMouseMove}>
<WrappedComponent {...this.props} mouse={this.state} />
</div>
);
}
};
}
// Использование
const TrackerDisplay = ({ mouse }) => <h2>({mouse.x}, {mouse.y})</h2>;
const EnhancedTracker = withMouseTracker(TrackerDisplay);
Такой подход сочетает мощь HOC для управления состоянием и Render Props (или просто передачу данных через props) для кастомного рендеринга, создавая максимально гибкую архитектуру компонентов.