Хук useTranslation

Хук useTranslation является центральным механизмом работы с переводами в связке react-i18next и библиотекой i18next. Он обеспечивает доступ к функциям перевода, управлению языком и состоянию интернационализации внутри функциональных React-компонентов.

Основная задача хука заключается в том, чтобы связать компонент с системой i18n-контекста и предоставить инструменты для получения локализованных строк, переключения языка и реакции на изменения языковой среды без необходимости использовать классовые компоненты или HOC-обёртки.

При вызове useTranslation компонент подписывается на i18next-контекст, который содержит текущий язык, загруженные ресурсы переводов и конфигурацию интернационализации. Это позволяет автоматически обновлять интерфейс при смене языка.

Функционально хук возвращает набор значений:

  • функция перевода t
  • экземпляр i18next i18n
  • состояние готовности перевода ready

Типичная структура:

const { t, i18n, ready } = useTranslation();

Функция t как ядро локализации

Основной инструмент, который предоставляет хук, — это функция t. Она извлекает перевод по ключу из ресурсов i18next.

Простейший пример использования:

const { t } = useTranslation();

return <h1>{t('welcome')}</h1>;

Здесь ключ welcome соответствует записи в словаре переводов текущего языка.

Интерполяция значений

Функция t поддерживает подстановку значений в строку:

t('greeting', { name: 'Alex' });

Ресурс перевода:

{
  "greeting": "Привет, {{name}}"
}

Результат: Привет, Alex

Работа с множественными формами

i18next поддерживает pluralization, а useTranslation позволяет использовать этот механизм напрямую через t.

t('cart.items', { count: 5 });

Ресурс:

{
  "cart": {
    "items_one": "{{count}} товар",
    "items_few": "{{count}} товара",
    "items_many": "{{count}} товаров"
  }
}

Логика выбора формы определяется правилами языка, заданными в конфигурации i18next.

Использование namespace в useTranslation

Одной из ключевых возможностей хука является работа с пространствами имён (namespaces). Они позволяют структурировать переводы по функциональным областям приложения.

const { t } = useTranslation('auth');

В этом случае все ключи будут искаться внутри namespace auth.

Также можно использовать несколько namespaces:

const { t } = useTranslation(['auth', 'common']);

Приоритет определяется порядком перечисления.

Объект i18n внутри useTranslation

Хук возвращает экземпляр i18next, который позволяет управлять языком и конфигурацией во время выполнения приложения.

Основные операции:

Смена языка

const { i18n } = useTranslation();

i18n.changeLanguage('en');

После вызова происходит перерендер всех компонентов, использующих переводы.

Получение текущего языка

console.log(i18n.language);

Проверка доступности языка

i18n.hasResourceBundle('en', 'common');

Параметр ready и загрузка ресурсов

При асинхронной загрузке переводов важно учитывать состояние готовности:

const { t, ready } = useTranslation();

if (!ready) return null;

Это предотвращает отображение ключей вместо переводов в момент инициализации.

Подключение нескольких namespace и fallback-логика

При работе с несколькими namespace i18next выполняет поиск ключа последовательно:

  1. текущий namespace
  2. дополнительные namespace в порядке объявления
  3. fallback language

Пример:

const { t } = useTranslation(['profile', 'common']);

Если ключ не найден в profile, он будет искаться в common.

Контекст обновления и реактивность

useTranslation подписывает компонент на изменения:

  • смена языка
  • загрузка новых ресурсов
  • изменение namespace
  • обновление конфигурации i18next

Это обеспечивает автоматический rerender без ручного управления состоянием.

Опции useTranslation

Хук принимает конфигурационный объект:

const { t } = useTranslation('common', {
  useSuspense: true,
  keyPrefix: 'dashboard'
});

useSuspense

Опция определяет поведение при загрузке переводов:

  • true — компонент приостанавливается до загрузки ресурсов
  • false — используется fallback или ключи

keyPrefix

Позволяет задавать общий префикс для ключей:

t('title'); // фактически common:dashboard.title

Использование с TypeScript

В связке с i18next можно типизировать ключи переводов:

const { t } = useTranslation();

t('home.title');

Расширенная типизация позволяет ограничивать набор доступных ключей и предотвращать ошибки на этапе компиляции.

Вложенные структуры переводов

i18next поддерживает глубокие объекты:

{
  "user": {
    "profile": {
      "title": "Профиль пользователя"
    }
  }
}

Использование:

t('user.profile.title');

Форматирование и функции в переводах

Поддерживаются не только строки, но и функции:

t('formatDate', { date: new Date() });

С соответствующей настройкой formatter в i18next.

Контекст языка и повторное использование хука

Хук можно вызывать в разных компонентах независимо. Все экземпляры синхронизируются через общий i18n-контекст.

function Header() {
  const { t } = useTranslation('common');
  return <h1>{t('title')}</h1>;
}

function Footer() {
  const { t } = useTranslation('common');
  return <footer>{t('copyright')}</footer>;
}

Изменение языка в любом месте приложения автоматически обновляет оба компонента.

Lazy-loading переводов

В крупных приложениях переводы часто загружаются динамически:

i18n.loadNamespaces('profile');

После загрузки useTranslation автоматически обновляет состояние компонентов, использующих этот namespace.

Особенности поведения при SSR

В серверном рендеринге важно, чтобы переводы были предварительно загружены. useTranslation в этом случае работает синхронно, используя уже подготовленный i18n-контекст.

Критический момент — совпадение языка сервера и клиента, чтобы избежать гидрационных расхождений.

Переиспользование t вне компонентов

Хотя useTranslation предназначен для React, функция t может быть получена из i18n напрямую:

import i18n from 'i18next';

i18n.t('key');

Однако такой подход лишает реактивности, которую обеспечивает хук.

Расширенные сценарии использования

Динамические ключи

t(`errors.${errorCode}`);

Условная локализация

t(isAdmin ? 'admin.panel' : 'user.panel');

Композиция ключей

const section = 'dashboard';
t(`${section}.title`);

Поведение при отсутствии ключа

Если ключ не найден, возвращается:

  • сам ключ (по умолчанию)
  • fallback значение (если задано)
  • обработчик отсутствующих переводов
t('unknown.key', 'Значение по умолчанию');