Higher-Order Component (HOC, компонент высшего порядка) — это продвинутая техника в React для повторного использования логики компонентов. HOC представляет собой функцию, которая принимает компонент и возвращает новый компонент с дополнительной функциональностью.
HOC можно сравнить с фабрикой компонентов, которая "оборачивает" исходный компонент и добавляет ему новые свойства или поведение.
const EnhancedComponent = withHOC(BaseComponent);
Где:
withHOC
— функция HOCBaseComponent
— исходный компонентEnhancedComponent
— новый улучшенный компонентfunction withLogger(WrappedComponent) {
return function(props) {
console.log('Rendering:', WrappedComponent.name);
return <WrappedComponent {...props} />;
};
}
// Использование
const ButtonWithLogger = withLogger(Button);
function withExtraProps(WrappedComponent, extraProps) {
return function(props) {
return <WrappedComponent {...props} {...extraProps} />;
};
}
// Использование
const ButtonWithColor = withExtraProps(Button, { color: 'red' });
function withAuth(WrappedComponent) {
return function(props) {
const [isAuthenticated] = useAuth();
if (!isAuthenticated) {
return <Redirect to="/login" />;
}
return <WrappedComponent {...props} />;
};
}
const ProtectedProfile = withAuth(Profile);
function withDataFetching(url) {
return function(WrappedComponent) {
return function(props) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch(url)
.then(res => res.json())
.then(data => {
setData(data);
setLoading(false);
});
}, []);
if (loading) return <Spinner />;
return <WrappedComponent data={data} {...props} />;
};
};
}
const PostListWithData = withDataFetching('/api/posts')(PostList);
<WrappedComponent {...this.props} {...newProps} />
WithAuth.displayName = `WithAuth(${getDisplayName(WrappedComponent)})`;
Критерий | HOC | Хуки |
---|---|---|
Сложность | Высокая | Низкая |
Гибкость | Ограниченная | Высокая |
Вложенность | Глубокая | Плоская |
Отладка | Сложная | Простая |
Performance | Может быть хуже | Обычно лучше |
Пример современной альтернативы с хуками:
// Вместо HOC
function useAuth() {
const [user] = useState(null);
return { user };
}
// В компоненте
const { user } = useAuth();