Что такое HOC (Higher Order Component) в React
Что проверяют
Знаете ли вы паттерн, понимаете ли его ограничения и осознаёте ли, что хуки заменили большую часть его применений.
Как отвечать
Компонент высшего порядка это функция, которая принимает компонент и возвращает новый компонент, добавляя ему поведение:
const withLogger = (Wrapped) => (props) => {
useEffect(() => console.log("mounted"), []);
return <Wrapped {...props} />;
};Это не часть API React, а приём, выросший из композиции функций. Классические примеры: connect из react-redux, withRouter, React.memo, обёртки для проверки прав доступа.
Появился он как способ переиспользовать логику между компонентами до хуков, когда альтернативами были только миксины и render props.
Ограничения, за которые обычно и спрашивают:
- вложенность обёрток: пять компонентов высшего порядка подряд превращают дерево в лестницу, по которой невозможно ходить в инструментах разработчика;
- столкновение пропсов: две обёртки передают проп с одним именем, и одна молча затирает другую;
refне проходит сквозь обёртку сам по себе, нуженforwardRef;- статические свойства теряются: обёрнутый компонент не наследует
Component.someStatic, отсюда библиотекаhoist-non-react-statics; - создание обёртки внутри рендера пересоздаёт тип компонента на каждом рендере, из-за чего поддерево полностью размонтируется и теряет состояние. Обёртку объявляют только на верхнем уровне модуля;
displayNameнадо задавать вручную, иначе в отладке будетAnonymous.
Сегодня для переиспользования логики берут свой хук: он не добавляет уровней в дерево, не конфликтует по именам и явно показывает, что откуда пришло. Компонент высшего порядка остаётся уместен там, где надо влиять на сам рендер: обёртка с обработкой ошибок, общий макет, подмена компонента по флагу функциональности.
Где спотыкаются
Не могут объяснить, чем это отличается от обычного компонента-обёртки.
Определяют обёртку внутри рендера и теряют состояние поддерева.
Не пробрасывают ref и остальные пропсы.
Используют компоненты высшего порядка там, где достаточно своего хука.