Назад

gt-react@10.12.0

Ernest McCarter avatarErnest McCarter
gt-reactgt-i18nv10.12.0tstring-translationbrowsersynchronousi18n

Обзор

gt-react теперь экспортирует функцию t() для синхронного перевода строк на уровне модуля в браузере.

Раньше для перевода строк в gt-react требовались хуки React, основанные на контексте, такие как useGT. Хуки хорошо работают внутри компонентов, но не покрывают распространённый сценарий: перевод строк на уровне модуля — вне компонентов React, до рендеринга, в обычных вспомогательных файлах.

t() решает эту задачу. Это синхронная функция, которую можно вызывать где угодно в браузерном коде:

import { t } from 'gt-react/browser';

const greeting = t('Hello, world!');

Не нужны ни hooks, ни async, ни дерево компонентов.

Почему именно такой подход

Основная идея этого PR — поэкспериментировать с отказом от подхода к переводу через контекст React. Поскольку t() работает вне дерева компонентов, он открывает более интересные паттерны — прежде всего перевод на уровне модуля. Строки можно переводить там, где они определены, а не там, где они рендерятся.

У этого подхода есть свои компромиссы:

  • Только на стороне клиента. t() работает только в клиентских React-приложениях. Он опирается на выполнение модулей в браузере, чтобы загрузить переводы до рендеринга приложения.
  • Для смены языка требуется полная перезагрузка страницы. Поскольку переводы определяются во время загрузки модуля, переключение локалей требует повторного выполнения модулей — то есть полной перезагрузки страницы. Горячее переключение языков прямо во время сессии не поддерживается.

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

Существующие подходы через контекст React (useGT, <T> и т. д.) никуда не денутся. Это дополнительный вариант для проектов, где такие компромиссы оправданы.

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

t() синхронно получает переводы из данных, загруженных заранее. Эти переводы подготавливаются с помощью bootstrap() — новой асинхронной функции настройки, которая загружает все переводы для текущей локали до отрисовки вашего приложения.

Вам нужно изменить точку входа вашего приложения, чтобы сначала запустить bootstrap(). Обычно это main.tsx, но вы можете изменить точку входа в index.html.

// bootstrap.tsx (новая точка входа)
import gtConfig from '../gt.config.json';
import { bootstrap } from 'gt-react/browser';

async function getTranslations(locale: string) {
  return import(`./_gt/${locale}.json`);
}

await bootstrap({
  ...gtConfig,
  getTranslations,
});

await import('./main.tsx');

Функция getTranslations асинхронная — сначала она загружает переводы, а затем импортируется и запускается React-приложение. Поэтому t() доступна на уровне модуля: к тому моменту, когда любой модуль вызывает t(), переводы уже загружены.

Это работает только в React-приложениях на стороне клиента, потому что код на уровне модуля заново выполняется при загрузке в браузере. А поскольку для изменения переведённого содержимого нужно заново выполнять модули, переключение локалей требует полной перезагрузки страницы.

Экспериментально: Сейчас эта возможность требует React-приложения, работающего только на стороне клиента.

Переменные

t() поддерживает подстановку переменных, как и msg():

import { t } from 'gt-react/browser';

t('Hello, {name}!', { name: 'John' });  // → "Hola, John!"

Где это применимо

t() — правильный выбор, когда переводы нужны вне дерева компонентов React: в файлах с константами, служебных функциях, объектах конфигурации, определениях маршрутов или в любом коде, который выполняется на уровне модуля в браузере.

Имейте в виду:

  • Пока это не интегрировано с остальной системой gt-react. Вам нужно выполнить описанную выше начальную настройку. Это автономный подход.
  • Только на стороне клиента. Для перевода на стороне сервера следует использовать хуки React, основанные на контексте, такие как useGT.

Примечания по реализации

t() работает только в браузере. Если вызвать её на сервере (где window не определён), будет выведено предупреждение, а вместо перевода будет использована исходная строка. Это сделано намеренно — для перевода на стороне сервера следует использовать существующие хуки React, основанные на контексте.


Справочник по API

См. полное справочное описание API t() с параметрами, типами возвращаемых значений и сведениями по настройке.