0Pricing
React Academy · Урок

Рефакторинг HOC в пользовательский хук

Пошагово преобразуйте HOC withAuth в хук useAuth.

«Рефакторинг HOC в пользовательский хук» — бесплатный урок React Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения React Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс React Academy содержит 4 уроков всего.

Добро пожаловать

В этом уроке Вы пошагово преобразуете HOC withAuth в пользовательский хук useAuth и точно увидите, почему версия с хуком получается чище и проще для тестирования.

HOC withAuth: исходный вариант

HOC принимает компонент, проверяет, авторизован ли пользователь, и перенаправляет его на /login, если нет. Он внедряет пользователя в качестве пропа.
function withAuth(Component) {
  return function AuthGuard(props) {
    const { user, loading } = useAuthState();
    if (loading) return <Spinner />;
    if (!user) return <Navigate to="/login" />;
    return <Component {...props} user={user} />;
  };
}

const ProtectedPage = withAuth(MyPage);

Проблемы HOC

HOC: (1) добавляет обёртку в DevTools, (2) неявно внедряет проп `user` — компонент должен знать, что его нужно ожидать, (3) сложно тестируется без отображения всей обёртки HOC, (4) плохо компонуется с другими хуками.

Шаг 1: извлечение логики в хук

Перенесите всю логику из HOC в пользовательский хук. Хук напрямую возвращает состояние авторизации — без обёртки и внедрения пропов.
function useAuth() {
  const { user, loading } = useAuthState();
  return { user, loading, isAuthenticated: !!user };
}

Шаг 2: обработка перенаправлений в хуке

Перенесите логику перенаправления в отдельный хук (например, useRequireAuth), который внутренне вызывает navigate и возвращает пользователя.
function useRequireAuth(redirectTo = '/login') {
  const { user, loading } = useAuth();
  const navigate = useNavigate();

  useEffect(() => {
    if (!loading && !user) navigate(redirectTo);
  }, [user, loading, navigate, redirectTo]);

  return { user, loading };
}

Шаг 3: обновление компонента

Замените обёртку HOC на прямой вызов хука внутри компонента. Компонент явно вызывает useRequireAuth и обрабатывает состояние загрузки. Теперь его зависимость видна непосредственно в коде.
function MyPage() {
  const { user, loading } = useRequireAuth();
  if (loading) return <Spinner />;
  return <p>Hello, {user.name}</p>;
}

Сравнение преимуществ

Версия с хуком: (1) не добавляет лишнюю обёртку в DevTools, (2) имеет явную зависимость — в компоненте виден вызов `useRequireAuth`, (3) тестируется с помощью имитации хука, (4) компонуется с другими хуками в том же компоненте.

Тестирование версии с хуком

В тесте имитируйте useRequireAuth, заменив экспорт модуля. Для теста компонента достаточно отобразить компонент и проверить результат — настройка HOC не требуется.
vi.mock('./useRequireAuth', () => ({
  useRequireAuth: () => ({ user: mockUser, loading: false })
}));

render(<MyPage />);
expect(screen.getByText('Hello, Alice')).toBeInTheDocument();

Когда стоит сохранить HOC

Сохраните HOC, если Вам нужно декларативно защищать множество компонентов (например, в определениях маршрутов) и Вы не хотите добавлять вызов хука в каждый из них. Можно даже построить HOC поверх хука.
function withAuth(Component) {
  return function (props) {
    const { user, loading } = useRequireAuth();
    if (loading) return <Spinner />;
    return <Component {...props} user={user} />;
  };
}

Лучшее из двух подходов

Итоговая архитектура: хук useRequireAuth для непосредственного использования в компонентах И тонкая обёртка HOC withAuth, построенная поверх него, для декларативной защиты маршрутов. Оба подхода используют одну и ту же логику хука.

Быстрая проверка

В чём главное преимущество вызова useRequireAuth внутри компонента по сравнению с его оборачиванием в HOC withAuth?

Итоги

Преобразуйте HOC в хуки, извлекая логику в пользовательский хук, перенося побочные эффекты (например, перенаправления) в хук и вызывая хук непосредственно в компоненте. Если нужна декларативная обёртка, создайте тонкий HOC поверх хука.

Курс завершён

Поздравляем! Вы завершили **Паттерны React: рендер-пропы и HOC**. Теперь Вы понимаете оба классических паттерна, их компромиссы и способы преобразования в современные пользовательские хуки.

Часто задаваемые вопросы

Урок «Рефакторинг HOC в пользовательский хук» бесплатный?

Да — полный текст урока «Рефакторинг HOC в пользовательский хук» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс React Academy, подпишись на CoddyKit PRO. Курс React Academy содержит 4 уроков всего.

Чему я научусь в уроке «Рефакторинг HOC в пользовательский хук»?

Пошагово преобразуйте HOC withAuth в хук useAuth. Ты практикуешь React Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать React Academy?

Предыдущий опыт не требуется. React Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.

Сколько времени занимает урок «Рефакторинг HOC в пользовательский хук»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке React Academy?

Да. Каждый урок React Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Паттерн Render Props
  2. Компоненты высшего порядка (HOC)
  3. HOC, Render Props или пользовательские хуки
  4. Рефакторинг HOC в пользовательский хук
← Назад к React Academy