← Назад к вопросам

Что такое higher-order-components?

1.0 Junior🔥 231 комментариев
#React

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое Higher-Order Components (HOC)

Higher-Order Component (HOC) — это продвинутый паттерн в React для повторного использования логики компонентов. HOC — это функция, которая принимает компонент и возвращает новый компонент с дополнительной функциональностью.

Определение и основная идея

// HOC — это функция
const withSubscription = (WrappedComponent) => {
  return (props) => {
    const [data, setData] = useState(null);

    useEffect(() => {
      const subscription = DataSource.subscribe(setData);
      return () => DataSource.unsubscribe(subscription);
    }, []);

    return <WrappedComponent data={data} {...props} />;
  };
};

// Использование
const EnhancedComponent = withSubscription(MyComponent);

Как это работает

  1. HOC получает компонент в качестве аргумента
  2. Создаёт новый компонент-обёртку
  3. Добавляет новую функциональность (данные, обработчики, состояние)
  4. Передаёт полученные пропсы исходному компоненту
  5. Возвращает новый компонент

Практические примеры

Пример 1: HOC для аутентификации

const withAuth = (Component) => {
  return (props) => {
    const [user, setUser] = useState(null);
    const [loading, setLoading] = useState(true);

    useEffect(() => {
      checkAuth().then(u => {
        setUser(u);
        setLoading(false);
      });
    }, []);

    if (loading) return <div>Loading...</div>;
    if (!user) return <div>Not authorized</div>;

    return <Component user={user} {...props} />;
  };
};

// Использование
const ProfilePage = withAuth(Profile);

Пример 2: HOC для подписки на тему

const withTheme = (Component) => {
  return (props) => {
    const [theme, setTheme] = useState('light');

    return (
      <ThemeContext.Provider value={{ theme, setTheme }}>
        <Component theme={theme} {...props} />
      </ThemeContext.Provider>
    );
  };
};

Пример 3: HOC для логирования пропсов

const withLogger = (Component) => {
  return (props) => {
    useEffect(() => {
      console.log('Component mounted with props:', props);
      return () => console.log('Component unmounted');
    }, [props]);

    return <Component {...props} />;
  };
};

HOC vs Hooks vs Render Props

HOC — плюсы:

  • Хорошо работает с классовыми компонентами
  • Ясная структура для обёртывания функциональности
  • Можно комбинировать несколько HOC

HOC — минусы:

  • Усложняет дерево компонентов (wrapper hell)
  • Может скрывать источник пропсов
  • Проблемы с ref передачей (нужна forwardRef)
  • В React Hooks era считается устаревшим подходом

Современный подход — Hooks:

// Вместо HOC используем кастомный хук
const useSubscription = () => {
  const [data, setData] = useState(null);
  
  useEffect(() => {
    const subscription = DataSource.subscribe(setData);
    return () => DataSource.unsubscribe(subscription);
  }, []);
  
  return data;
};

// Использование
function MyComponent() {
  const data = useSubscription();
  return <div>{data}</div>;
}

Правила использования HOC

  1. Не используй HOC в render-методе (пересоздание компонента)
  2. Передавай все пропсы через {...props}
  3. Копируй статические методы исходного компонента
  4. Используй displayName для отладки
const withSomething = (Component) => {
  function WithSomething(props) {
    return <Component {...props} />;
  }
  
  WithSomething.displayName = `WithSomething(${Component.displayName || Component.name})`;
  
  return WithSomething;
};

Когда использовать HOC

  • Для миграции старого кода (legacy классовые компоненты)
  • Для библиотек, которые полагаются на HOC (Redux connect, React Router)
  • Когда нужна функциональность на уровне компонента

Современная альтернатива

Сегодня вместо HOC используй:

  • Custom Hooks — самый простой и читаемый способ
  • Context API — для глобального состояния
  • Composition — просто вкладывай компоненты друг в друга