HOC (Higher-Order Component) — это паттерн проектирования в React, позволяющий создавать компоненты более высокого уровня на основе существующих. Идея заключается в том, что HOC принимает компонент и возвращает новый компонент с расширенной функциональностью. По сути, HOC — это функция, которая оборачивает другой компонент, добавляя ему новые свойства, логику или поведение.
HOC используется для повторного использования логики между компонентами. Вместо дублирования кода в нескольких местах можно создать обёртку, которая управляет общей функциональностью, и применять её к любому компоненту.
Схема работы HOC:
const EnhancedComponent = higherOrderComponent(WrappedComponent);
WrappedComponent — исходный компонент, который требует
дополнительной логики.higherOrderComponent — функция, которая добавляет
функциональность.EnhancedComponent — новый компонент с расширенными
возможностями.Предположим, есть компонент, который выводит текст:
const SimpleComponent = ({ text }) => <div>{text}</div>;
Можно создать HOC, который будет добавлять логирование при рендере:
function withLogging(WrappedComponent) {
return function(props) {
console.log('Рендер компонента с пропсами:', props);
return <WrappedComponent {...props} />;
};
}
const EnhancedComponent = withLogging(SimpleComponent);
При использовании EnhancedComponent в консоли будет
выводиться информация о пропсах, переданных компоненту.
HOC обычно работает с пропсами исходного компонента. Для корректной передачи данных важно использовать spread-оператор:
return <WrappedComponent {...props} />;
Это гарантирует, что все пропсы будут переданы обёрнутому компоненту без потерь.
Повторное использование логики Например, авторизация, логирование, обработка ошибок.
Управление состоянием HOC может добавлять состояние или методы для управления внутренними данными компонента.
Обработка данных Например, выборка данных с сервера или фильтрация массива перед передачей компоненту.
Композиция функций Несколько HOC можно комбинировать, создавая цепочку обёрток:
const ComposedComponent = withLogging(withAuth(SimpleComponent));
function withLogging(WrappedComponent) {
function Enhanced(props) {
console.log('Рендер:', props);
return <WrappedComponent {...props} />;
}
Enhanced.displayName = `WithLogging(${WrappedComponent.displayName || WrappedComponent.name || 'Component'})`;
return Enhanced;
}
Enzyme позволяет тестировать как исходные компоненты, так и обёрнутые HOC. Важные моменты:
import { shallow } from 'enzyme';
const wrapper = shallow(<EnhancedComponent text="Привет" />);
expect(wrapper.text()).toContain('Привет');
const InnerComponent = EnhancedComponent.WrappedComponent || SimpleComponent;
const wrapper = shallow(<InnerComponent text="Привет" />);
expect(wrapper.props().text).toBe('Привет');
HOC актуален, когда требуется обёртка и расширение поведения компонента, особенно для классовых компонентов или для библиотек, где функциональные хуки не подходят.
HOC представляет собой мощный инструмент, позволяющий создавать масштабируемые и поддерживаемые приложения, сокращая дублирование кода и централизуя логику.