Свойства рендеринга и шаблоны HOC
Передавайте функцию рендеринга как свойство для внедрения пользовательского интерфейса и оборачивайте компоненты в компоненты высшего порядка, чтобы внедрять поведение без изменения оригинала
«Свойства рендеринга и шаблоны HOC» — бесплатный урок Frontend Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Frontend Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Frontend Academy содержит 4 уроков всего.
Два классических шаблона повторного использования
До появления хуков (React 16.8) повторное использование логики с состоянием означало выбор между компонентами высшего порядка (HOC) и свойствами рендеринга. В новом коде они встречаются редко, но Вы по-прежнему встретите их в устаревших кодовых базах и многих библиотеках.
Свойства рендеринга — идея
Компонент принимает функцию в качестве свойства (обычно с именем render или children) и вызывает её с внутренним состоянием. Пользователь компонента решает, что отрисовать с этим состоянием.
function Mouse({ render }) {
const [pos, setPos] = useState({ x: 0, y: 0 });
useEffect(() => {
const handler = (e) => setPos({ x: e.clientX, y: e.clientY });
window.addEventListener('mousemove', handler);
return () => window.removeEventListener('mousemove', handler);
}, []);
return render(pos);
}
// Usage:
<Mouse render={({ x, y }) => <p>{x}, {y}</p>} />children как функция
Свойство children также может быть функцией — тот же шаблон с более чистым JSX.
function Mouse({ children }) {
const [pos, setPos] = useState({ x: 0, y: 0 });
/* ... */
return children(pos);
}
<Mouse>
{({ x, y }) => <p>{x}, {y}</p>}
</Mouse>Компоненты высшего порядка — идея
HOC — это функция, которая принимает компонент и возвращает новый компонент с дополнительными свойствами или поведением. Этот подход активно использовался в Redux через connect() и в React Router через withRouter().
function withMouse(Component) {
return function WithMouse(props) {
const [pos, setPos] = useState({ x: 0, y: 0 });
useEffect(() => {
const handler = (e) => setPos({ x: e.clientX, y: e.clientY });
window.addEventListener('mousemove', handler);
return () => window.removeEventListener('mousemove', handler);
}, []);
return <Component {...props} mouse={pos} />;
};
}
// Usage:
const Position = ({ mouse }) => <p>{mouse.x}, {mouse.y}</p>;
const EnhancedPosition = withMouse(Position);
<EnhancedPosition />HOC объединяются обёртыванием
Можно выстроить несколько HOC в цепочку, но они образуют «ад обёрток», в котором сложно искать ошибки.
// Multiple HOCs:
const Enhanced = withRouter(connect(mapState)(withTranslation()(MyComponent)));
// Equivalent in modern React:
// const Enhanced = MyComponent (reads from hooks: useRouter, useSelector, useTranslation)Свойства рендеринга и HOC
Свойства рендеринга: более явные, удобные для типизации, без конфликтов имён. HOC: более декларативные; без осторожности обёрнутые компоненты теряют статические типы, также возможны конфликты имён свойств.
Почему хуки заменили оба подхода
Пользовательские хуки достигают той же цели с меньшим количеством служебного кода: без компонентов-обёрток, вложенных аргументов-функций и сложных манипуляций с типами. В 2025 году хуки — идиоматичный подход.
// Custom hook equivalent of useMouse:
function useMouse() {
const [pos, setPos] = useState({ x: 0, y: 0 });
useEffect(() => {
const handler = (e) => setPos({ x: e.clientX, y: e.clientY });
window.addEventListener('mousemove', handler);
return () => window.removeEventListener('mousemove', handler);
}, []);
return pos;
}
// Usage:
const { x, y } = useMouse();Когда свойства рендеринга всё ещё лучше
Для компонентов, которым нужно добавлять разметку, а не только состояние, например для виртуализированных списков, отрисовывающих элементы в определённых позициях, свойства рендеринга по-прежнему подходят лучше всего.
function VirtualList({ items, itemHeight, renderItem }) {
const [scrollTop, setScrollTop] = useState(0);
const start = Math.floor(scrollTop / itemHeight);
const visible = items.slice(start, start + 20);
return visible.map((item, i) => renderItem(item, start + i));
}
<VirtualList items={data} itemHeight={40} renderItem={(item, i) => (
<Row key={i} data={item} />
)} />Рекомендации по HOC при необходимости
Если необходимо написать HOC: копируйте статические методы (hoist-non-react-statics), передавайте ссылки (React.forwardRef) и сохраняйте displayName для DevTools.
Передача ссылок в HOC
По умолчанию HOC скрывают ссылки — используйте forwardRef, чтобы пользователи по-прежнему могли обращаться к ссылке базового компонента.
function withLogger(Component) {
const Wrapped = React.forwardRef((props, ref) => {
console.log('rendering', Component.name);
return <Component {...props} ref={ref} />;
});
Wrapped.displayName = `withLogger(${Component.name})`;
return Wrapped;
}Как распознать устаревшие шаблоны
Вы встретите HOC и свойства рендеринга в react-redux (старый API), Apollo Client v2, react-router v5 (withRouter), Formik (Field) и styled-components (withTheme). Переписывайте их с использованием хуков, когда новые API этих библиотек это позволяют.
Быстрая проверка
Какой шаблон хуки в основном заменили для совместного использования логики с состоянием между компонентами React?
Итоги: свойства рендеринга и HOC
Свойства рендеринга: функция в качестве свойства, возвращающая JSX; явный и удобный для типизации подход. HOC: функция, оборачивающая компонент; используется старыми библиотеками (connect, withRouter). Пользовательские хуки заменили оба подхода для логики состояния. Свойства рендеринга по-прежнему лучше, когда нужно добавлять пользовательскую разметку (виртуализированные списки). При написании HOC: используйте forwardRef, переносите статические свойства и задавайте displayName.
Часто задаваемые вопросы
Урок «Свойства рендеринга и шаблоны HOC» бесплатный?
Да — полный текст урока «Свойства рендеринга и шаблоны HOC» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Frontend Academy, подпишись на CoddyKit PRO. Курс Frontend Academy содержит 4 уроков всего.
Чему я научусь в уроке «Свойства рендеринга и шаблоны HOC»?
Передавайте функцию рендеринга как свойство для внедрения пользовательского интерфейса и оборачивайте компоненты в компоненты высшего порядка, чтобы внедрять поведение без изменения оригинала Ты практикуешь Frontend Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Frontend Academy?
Предыдущий опыт не требуется. Frontend Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.
Сколько времени занимает урок «Свойства рендеринга и шаблоны HOC»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Frontend Academy?
Да. Каждый урок Frontend Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Составные компоненты с Context
- Свойства рендеринга и шаблоны HOC
- Порталы для модальных окон и подсказок
- Границы ошибок