Строки

Как локализовать простые текстовые строки с помощью useGT

Перевод строк дает прямой доступ к текстовым переводам без JSX — это удобно для атрибутов, свойств объектов и простых текстовых значений. Используйте useGT в компонентах React для перевода строк.

Быстрый старт

import { useGT } from 'gt-react';

function MyComponent() {
  const t = useGT();
  return (
    <input 
      placeholder={t('Введите вашу электронную почту')}
      title={t('Поле для ввода электронной почты')}
    />
  );
}

Когда использовать перевод строк

Перевод строк уместен, когда нужен обычный текст, а не JSX:

Атрибуты HTML

const t = useGT();

<input 
  placeholder={t('Поиск товаров...')}
  aria-label={t('Поле для поиска товаров')}
  title={t('Введите текст, чтобы искать по нашему каталогу')}
/>

Свойства объекта

const t = useGT();

const user = {
  name: 'John',
  role: 'admin',
  bio: t('Опытный разработчик ПО с 5-летним опытом работы с React'),
  status: t('Доступен для новых проектов')
};

Конфигурация и константы

const t = useGT();

const navigationItems = [
  { label: t('Главная'), href: '/' },
  { label: t('Продукты'), href: '/products' },
  { label: t('Связаться'), href: '/contact' }
];

Когда лучше использовать <T>

Используйте компонент <T> для JSX‑контента:

// ✅ Используйте <T> для JSX-контента
<T><p>Добро пожаловать в <strong>наш магазин</strong>!</p></T>

// ✅ Используйте строковый перевод для обычного текста
<input placeholder={t('Поиск товаров')} />

Работа с переменными

Базовые переменные

Заменяйте заполнители динамическими значениями:

const t = useGT();
const itemCount = 5;

// String with placeholder
const message = t('У вас {count} товаров в корзине', { count: itemCount });
// Результат: «У вас 5 товаров в корзине»

Несколько переменных

const t = useGT();
const order = { id: 'ORD-123', total: 99.99, date: '2024-01-15' };

const confirmation = t(
  'Заказ {orderId} на сумму ${total} был оформлен {date}',
  { 
    orderId: order.id, 
    total: order.total, 
    date: order.date 
  }
);

Формат сообщений ICU

Для расширенного форматирования используйте синтаксис ICU:

const t = useGT();
translate('В корзине {count, plural, =0 {нет товаров} =1 {один товар} few {{count} товара} many {{count} товаров} other {{count} товара}}', { count: 10 });

Подробнее о формате сообщений ICU — в документации Unicode.

Примеры

Поля ввода формы

import { useGT } from 'gt-react';

function ContactForm() {
  const t = useGT();
  
  return (
    <form>
      <input 
        type="email"
        placeholder={t('Введите адрес электронной почты')}
        aria-label={t('Поле для ввода электронной почты')}
      />
      <textarea 
        placeholder={t('Расскажите о своём проекте...')}
        aria-label={t('Описание проекта')}
      />
      <button type="submit">
        {t('Отправить сообщение')}
      </button>
    </form>
  );
}

Меню навигации

import { useGT } from 'gt-react';

function Navigation() {
  const t = useGT();
  
  const menuItems = [
    { label: t('Главная'), href: '/', icon: 'home' },
    { label: t('О компании'), href: '/about', icon: 'info' },
    { label: t('Услуги'), href: '/services', icon: 'briefcase' },
    { label: t('Связаться'), href: '/contact', icon: 'mail' }
  ];

  return (
    <nav>
      {menuItems.map((item) => (
        <a key={item.href} href={item.href} title={item.label}>
          <Icon name={item.icon} />
          {item.label}
        </a>
      ))}
    </nav>
  );
}

Фабрика динамического контента

// utils/productData.js
export function getProductMessages(t) {
  return {
    categories: [
      { id: 'electronics', name: t('Электроника') },
      { id: 'clothing', name: t('Одежда') },
      { id: 'books', name: t('Книги') }
    ],
    statusMessages: {
      available: t('В наличии, готово к отправке'),
      backordered: t('Сейчас доступен по предзаказу — отправка через 2–3 недели'),
      discontinued: t('Этот товар снят с производства')
    },
    errors: {
      notFound: t('Товар не найден'),
      outOfStock: t('К сожалению, этот товар сейчас отсутствует на складе')
    }
  };
}

// components/ProductCard.jsx
import { useGT } from 'gt-react';
import { getProductMessages } from '../utils/productData';

function ProductCard({ product }) {
  const t = useGT();
  const messages = getProductMessages(t);
  
  return (
    <div>
      <h3>{product.name}</h3>
      <p>{messages.statusMessages[product.status]}</p>
      <span>{messages.categories.find(c => c.id === product.categoryId)?.name}</span>
    </div>
  );
}

Компонент с заголовком страницы

import { useGT } from 'gt-react';
import { useEffect } from 'react';

function ProductPage() {
  const t = useGT();
  
  useEffect(() => {
    document.title = t('Каталог товаров — найдите всё, что вам нужно');
    
    // Обновить метаописание
    const metaDescription = document.querySelector('meta[name="description"]');
    if (metaDescription) {
      metaDescription.setAttribute('content', t('Ознакомьтесь с нашей обширной подборкой качественных товаров'));
    }
  }, [t]);
  
  return (
    <div>
      <h1>{t('Избранные товары')}</h1>
      <p>{t('Ознакомьтесь с нашими новинками и самыми популярными товарами')}</p>
    </div>
  );
}

Типичные проблемы

Динамический контент во время выполнения

Строки должны быть известны на этапе сборки — перевести динамический контент нельзя:

// ❌ Динамический контент не будет работать
function MyComponent() {
  const [userMessage, setUserMessage] = useState('');
  const t = useGT();
  
  return <p>{t(userMessage)}</p>; // Это вызовет ошибку
}

// ✅ Используйте заранее определённые строки
function MyComponent() {
  const [messageType, setMessageType] = useState('welcome');
  const t = useGT();
  
  const messages = {
    welcome: t('Добро пожаловать в наше приложение!'),
    goodbye: t('Спасибо, что заглянули!')
  };
  
  return <p>{messages[messageType]}</p>;
}

Нарушения правил хуков

Соблюдайте правила хуков React при использовании useGT:

// ❌ Не вызывайте хуки условно
function MyComponent({ showMessage }) {
  if (showMessage) {
    const t = useGT(); // Нарушение правила хуков
    return <p>{t('Привет!')}</p>;
  }
  return null;
}

// ✅ Всегда вызывайте хуки на верхнем уровне
function MyComponent({ showMessage }) {
  const t = useGT();
  
  if (showMessage) {
    return <p>{t('Привет!')}</p>;
  }
  return null;
}

Для действительно динамического контента, который требует перевода во время выполнения, см. руководство по динамическому контенту Dynamic Content Guide.

Дальнейшие шаги

  • Dynamic Content Guide - Обработка переводов во время выполнения
  • Shared Strings Guide - Организация повторно используемых переводов
  • Справочные материалы по API:

Насколько полезно это руководство?

Строки