React i18n: пошаговое руководство по React-intl
- Published on
- Authors
- Name
- Vasiliy Kramarenko
- @kramvas07
Интернационализация или i18n — это дизайн и разработка продукта, приложения или содержимого документа, которые позволяют легко локализовать его для целевых аудиторий, которые различаются по культуре, региону или языку.
Таким образом, React i18n занимается локализацией приложений React для разных языков.
Целью интернационализации является устранение барьеров для локализации или развертывания приложения на международном уровне. Использование Unicode, устаревшие кодировки символов, конкатенация строк и т. д., вот некоторые из вещей, которые помогают в разработке приложения для обеспечения успешной интернационализации.
Эта статья представляет собой подробное руководство о том, как работать с React-intl для интернационализации вашего приложения React. Мы обсудим следующие темы:
- Популярные библиотеки для React i18n.
- Начало работы с React-intl.
- Использование аргументов в переведенном тексте.
- Создание селектора языкового стандарта для переключения между языками.
- Перевод даты, времени, чисел и валют в разные страны.
- Множественное число с React-intl.
Вам также может быть интересно узнать, как переводить приложения React с помощью I18next или как локализовать React Native.
Что такое локализация?
Локализация означает адаптацию продукта, приложения или содержимого документа для удовлетворения лингвистических, культурных и других требований конкретного целевого рынка (региона). Часто известный как l10n, некоторые ошибочно принимают его за простой перевод содержимого приложения в соответствие с языковым стандартом. Фактически, локализация выходит за рамки перевода. С помощью локализации вы можете настроить не только языковые предпочтения, но и числовые форматы, форматы даты и времени, валютные форматы, раскладку клавиатуры, сортировку и сбор, направление текста и даже цвета и дизайн.
Не останавливаясь на достигнутом, локализация может даже вызвать необходимость переосмыслить логику приложения и его дизайн. Когда вы ориентируетесь на конкретный рынок, вы должны адаптировать его обычаи под свои собственные.
Предпосылки
В этом руководстве предполагается, что вы установили на свое устройство последнюю версию Node.js и npm. Вы также должны быть знакомы с HTML, JavaScript и базовыми командами npm или Yarn, прежде чем изучать React i18n.
Введение в React
React — популярная библиотека JavaScript для создания компонентов пользовательского интерфейса, разработанная Facebook. Отличие React в том, что он не манипулирует напрямую DOM, а создает виртуальный DOM в памяти. Прежде чем вносить изменения в DOM браузера, он выполняет все изменения в виртуальном дереве.
Установка
Во-первых, вам нужно установить приложение create-react-app, вы можете сделать это, введя следующую команду в вашем терминале командной строки:
npm install -g create-react-app
Создайте папку в нужном месте и откройте ее в текстовом редакторе, а затем откройте окно терминала в текстовом редакторе и введите эту команду:
npx react-create-app <name_of_your_app>
После этого вы увидите, что приложение было создано с предопределенной структурой папок внутри него. Вам будет предложено перейти в созданное вами приложение и запустить npm start или yarn start, в зависимости от того, какой менеджер пакетов вы установили на свой компьютер.
После запуска npm start или yarn start в вашем браузере по умолчанию откроется новая вкладка, загружающая приложение, которое вы только что создали по адресу localhost:3000, которое будет выглядеть так:
Популярные библиотеки для React i18n
Давайте изучим и соберем информацию о некоторых хорошо известных библиотеках React i18n. Выбор подходящего пакета или библиотеки может оказаться не таким простым, как кажется. React-intl, плагин Gatsby и react-i18next — одни из самых популярных библиотек для React i18n.
При выборе подходящего пакета учитывайте следующие факторы:
- Пакеты, похожие на те, которые вы используете для другого проекта.
- Соответствует ли пакет вашим потребностям и потребностям ваших пользователей?
- Ваша команда уже знакома с пакетом в списке, из которого вы собираетесь выбирать?
- Документация и сопровождение пакета.
React-intl
Библиотека react-intl входит в состав библиотек интернационализации FormatJS. Она поддерживает более 150 языков по всему миру. Этот продукт, предлагаемый Yahoo, в основном популярен благодаря встроенным в него функциям. Общие настройки локали, такие как дата и время, валюта и числа, можно легко обрабатывать с помощью response-intl. Кроме того, у него есть обширная документация, соответствующая передовым стандартам, с использованием встроенных в браузер переводов везде, где это возможно. Параметры полифилла можно использовать с браузерами, которые не поддерживают JavaScript API для i18n.
React-intl основан на API JavaScript для React i18n и предлагает улучшенные API и компоненты. Когда вам нужно динамически загружать языковые модули, react-intl использует контекст React и компоненты более высокого порядка, которые предоставляют переводы.
Вы можете обратиться к документации response-intl здесь.
В этом руководстве мы будем использовать библиотеку react-intl для применения интернационализации, поскольку это лучшая и самая популярная библиотека для React i18n на сегодняшний день.
React-intl-universal
Пакет интернационализации react-intl-universal, созданный Alibaba Group, основан на библиотеке react-intl. Разница в том, что эта библиотека позволяет даже компонентам, не относящимся к React, использовать библиотеку, предоставляя одноэлементный объект для загрузки локали. Например, это можно использовать в Vanilla JS, как указано в самой документации.
Более того, эта библиотека проста в использовании, поскольку содержит только три основных API и дополнительный помощник. Вы можете использовать это для загрузки чисел, валюты, даты и времени на разных языках. Помимо этого, включено множественное число, которое позволяет вам определять метки для строк. Формат сообщения реализован с использованием стандартов ICU, и даже вложенные формы данных в формате JSON поддерживаются через него.
Вы можете обратиться к документации на response-intl-universal здесь.
React-i18next
На основе инфраструктуры React i18n, react-i18next — еще одна популярная библиотека интернационализации, которая использует компоненты для рендеринга или повторного рендеринга переведенного контента вашего приложения, когда пользователи запрашивают смену языка.
Эта библиотека предназначена для добавления новых функций и внесения изменений в широкий спектр плагинов, конфигураций и утилит. Определение предпочтительных языков пользователя, кэширование локали, загрузка переведенного контента с внутреннего сервера и связывание переводов с веб-пакетом — вот некоторые из функций, выполняемых этими плагинами.
React-i18next также обеспечивает экспериментальную поддержку API в режиме ожидания React.
Вы можете обратиться к документации React-i18next здесь.
LinguiJS
Хотя LinguiJS является новичком в области интернационализации, он предлагает ряд полезных функций для интернационализации вашего приложения. Это простой пакет с меньшими накладными расходами.
Вы можете обратиться к документации LinguiJS здесь.
Начало работы с React-intl
Установка
Вы можете установить библиотеку response-intl, введя следующую команду в терминале или командной строке:
npm i -S react-intl
или
yarn add react-intl
Рабочий процесс приложения
Мы разработаем наше приложение в соответствии со структурой папок ниже:
Ознакомьтесь с полным кодом на GitHub.
В демонстрационном приложении мы будем использовать три языка: русский, английский и арабский.
Когда мы разрабатываем наше приложение для поддержки интернационализации, один из основных вопросов заключается в том, как определить предпочтительный язык пользователя. Обычно пользователи определяют предпочтительные языковые настройки в своих браузерах. Таким образом, мы можем дать им лучший пользовательский опыт, определив их язык и предоставив контент на этом языке.
Во всех современных браузерах есть объект navigator.language, который можно использовать для получения языковых настроек пользователя.
Теперь вот как наш файл index.js будет выглядеть в начале:
import React from 'react';
import ReactDOM from 'react-dom';
import { IntlProvider } from 'react-intl';
import './index.css';
import App from './App';
import Russian from './lang/ru.json';
import Arabic from './lang/ar.json';
import English from './lang/en.json';
const locale = navigator.language;
let lang;
if (locale==="en") {
lang = English;
} else {
if (locale === "ru") {
lang = Russian;
} else {
lang = Arabic;
}
}
ReactDOM.render(
<React.StrictMode>
<IntlProvider locale ={locale} messages={Russian}>
<App />
</IntlProvider>
</React.StrictMode>,
document.getElementById('root')
);
Здесь, как вы видите, мы выполнили 4 импорта: IntlProvider и три языковых файла: ru.json, en.json и ar.json.
Здесь, как вы видите, мы выполнили 4 импорта: IntlProvider и три языковых файла: ru.json, en.json и ar.json.
Шаблон провайдера используется библиотекой response-intl для установки области контекста интернационализации в виде дерева компонентов. Это заворачивает корневой компонент приложения, и все приложение будет настроено в контексте интернационализации. Затем мы объявим постоянную переменную для навигации по языку с помощью navigator.language.
Добавление переводов
Мы должны добавить соответствующие переведенные сообщения в языковые файлы. Создайте подкаталог в папке src как «lang» и добавьте три файла с именами ru.json, en.json и ar.json, если вы еще этого не сделали. Затем добавьте в файлы следующее содержимое. Обратите внимание, что вы всегда можете изменить и добавить свой собственный текст.
lang/ru.json file
{
"app.header" : "Отредактируйте файлы и сохраните, чтобы перезагрузить" ,
"app.content" : "Изучите React" ,
"app.channel.plug": "Учебник предоставлен вам Medium"
}
lang/en.json file
{
"app.header" : "Edit the files and save to reload" ,
"app.content" : "Learn React" ,
"app.channel.plug": "Tutorial brought to you by Medium"
}
lang/ar.json file
{
"app.header" : "قم بتحرير الملفات وحفظها لإعادة التحميل" ,
"app.content" : "تعلم React" ,
"app.channel.plug": "يقدم لك البرنامج التعليمي Medium"
}
Объявление сообщений
FormatJS использует синтаксис ICU с некоторыми улучшениями в объявлении сообщений. Существует несколько способов вызова API-интерфейсов FormatJS для объявления и извлечения сообщений. Давайте посмотрим на некоторые из них сейчас.
- intl.formatMessage — обязательный API:
intl.formatMessage(
{
description: 'A message',
defaultMessage: 'My name is {name}',
},
{
name: userName,
}
);
И description, и defaultMessage должны быть строковыми литералами, а значения должны быть объектными литералами. Поскольку AST используется для извлечения сообщений из кодовой базы, функция должна вызываться intl.formatMessage() точно так же, как она есть. Используя другие формы, такие как formatMessage, const {formatMessage: f} = intl; f() работать не будет.
2. FormattedMessage — ReactAPI:
import {FormattedMessage} from 'react-intl';
<FormattedMessage
description="message"
defaultMessage="Welcome {username}"
values={
{
username: userName,
}
}
/>;
Опять же, по той же причине, что упомянута выше, вы должны использовать FormattedMessage именно так, как есть. const F = FormattedMessage; <F /> или другие подобные методы работать не будут.
3. defineMessage — предварительно заявлено для дальнейшего использования:
import {defineMessage} from 'react-intl';
const message = defineMessage({
description: 'message',
defaultMessage: 'Welcome {username}',
});
intl.formatMessage(message, {username: ''}); // Welcome Vasiliy
<FormattedMessage
{...message}
values={{
username: 'Vasiliy',
}}
/>; // Welcome Vasiliy
Этот метод объявления сообщения менее рекомендуется. Как указано в документации FormatJS, мы можем объявлять сообщения без необходимости их немедленного форматирования с помощью defineMessage, и их экстрактор по-прежнему будет извлекать их. Проблема в правиле линтера; enforce-placeholder не сможет его проанализировать.
Отражая изменения
Получив приведенный выше код, мы изменим файл App.js, чтобы отобразить изменения. Здесь мы выполнили объявление сообщения, используя второй метод, который мы обсуждали.
App.js:
import React from 'react';
import logo from './logo.svg';
import './App.css';
import {FormattedMessage} from 'react-intl';
function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
<FormattedMessage
id = "app.header"
defaultMessage="Edit the files and save to reload"
/>
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
<FormattedMessage
id = "app.content"
defaultMessage="Learn React"
/>
</a>
<FormattedMessage
id = "app.channel.plug"
defaultMessage="Tutorial brought to you by Medium"
/>
</header>
</div>
);
}
export default App;
Мы импортировали сюда FormattedMessage, чтобы получать сообщения. Поскольку теперь мы определили переведенные строки в файле JSON, объявленные идентификаторы должны использоваться при присвоении имен строкам. Например, идентификатор сообщения Learn React — app.content.
Использование defaultMessage, наряду с его использованием, поощряется сообществом FormatJS по причинам, перечисленным ниже:
- Сообщения, которые размещены вместе с чем-то другим, особенно с их использованием, станут самоуправляемыми, и если использование будет удалено или изменено, сообщения тоже будут.
- Разработчики пишут сообщения, исходя из определенного типа грамматики, и они очень контекстны.
- Стиль текста сообщения зависит от сообщения. Например, использование заглавных букв, усечение и т. Д. Влияет на сообщения.
- Это обеспечивает лучшую интеграцию при использовании с цепочками инструментов, поскольку многие цепочки инструментов не могут проверять или подтверждать ссылки между файлами при проверке синтаксиса.
После того, как вы закончите вносить изменения, запустите npm start и загрузите http://localhost:3000/ в свой браузер. Если вы уже выполнили команду и сервер запущен, эти изменения вступят в силу автоматически.
Эти изменения приведут к отображению пользовательского интерфейса, как показано ниже:
Если вы до сих пор все сделали правильно, теперь контент вашего интерфейса будет на русском языке.
Добавление аргументов / заполнителей
Теперь, когда у нас хорошее начало, давайте посмотрим, как можно внести небольшие изменения. Не все хотят сейчас просто сказать «Учебник, представлен вам Medium», не так ли? Вы должны иметь возможность добавлять все, что хотите, а это значит, что у нас должна быть возможность иметь переменную вместо жестко заданного заголовка блога. Например, вы можете добавить персональное приветственное сообщение с именем пользователя в нем.
В React i18n очень просто добавить переменную среди переведенных строк. Все, что вам нужно сделать, это включить переменную в файл JSON в пару фигурных скобок и получить к ней доступ из того места, где вы используете строку. Посмотрите следующий пример:
lang/en.json
{
"app.channel.plug": "Учебник предоставлен вам {blogName}"
}
Как видите, я не включил здесь название нашего блога “Medium”. Вместо этого в фигурные скобки заключена переменная как blogName.
Теперь, в отформатированном сообщении в файле App.js, включите еще один ключ в качестве «значений», и там вы должны указать свое имя переменной, а значение для этой переменной указано ниже:
<FormattedMessage
id = "app.channel.plug"
defaultMessage="Учебник, представлен вам Medium"
values = {{blogName: "Medium"}}
/>
Вы все равно увидите результат, как и раньше, если вы все сделали правильно.
Пройдя немного дальше по добавлению переменных, вы можете увидеть, что исходный файл App.js содержит сообщение «Отредактируйте файлы и сохраните для перезагрузки» как ‘Edit<code>{fileName}</code> js and save to reload’
Теперь, чтобы отразить изменения, все, что вам нужно сделать, это добавить кое-что в свой FormattedMessage.
<FormattedMessage
id = "app.header"
defaultMessage="Edit the files and save to reload"
values = {{fileName: 'src/App.js', code: (word)=> <code>{word}</code>}}
/>
Единственное, что вам нужно помнить, это то, что тег, который вы указали в языковом файле, должен быть тем же словом, которое вы используете здесь в качестве ключа. Остальные можно менять по желанию. Возьмите, например, приведенный ниже фрагмент кода:
<FormattedMessage
id = "app.header"
defaultMessage="Edit the files and save to reload"
values = {{fileName: 'src/App.js', code: (word)=> <strong>{word}</strong>}}
/>
Это по-прежнему будет выводить полужирным шрифтом — другой стиль:
Создание селектора языкового стандарта в React i18n
Затем давайте посмотрим, как мы можем изменить язык с помощью раскрывающегося меню, а не жестко запрограммированным способом.
Добавление обертки
Создайте новый подкаталог в папке src и назовите его «components». Затем добавьте в него файл JS и назовите его «Wrapper.js». Включите показанный здесь код в свой файл, и теперь я объясню, что было сделано в этом файле.
components/Wrapper.js:
import React, {useState} from 'react';
import {IntlProvider} from 'react-intl';
import Russian from '../lang/ru.json';
import Arabic from '../lang/ar.json';
import English from '../lang/en.json';
const Context = React.createContext();
const local = navigator.language;
let lang;
if (local === 'en') {
lang = English;
}else {
if (local === 'ru') {
lang = Russian;
} else {
lang = Arabic;
}
}
const Wrapper = (props) => {
const [locale, setLocale] = useState(local);
const [messages, setMessages] = useState(lang);
function selectLanguage(e) {
const newLocale = e.target.value;
setLocale(newLocale);
if (newLocale === 'en') {
setMessages(English);
} else {
if (newLocale === 'ru'){
setMessages(Russian);
} else {
setMessages(Arabic);
}
}
}
return (
<Context.Provider value = {{locale, selectLanguage}}>
<IntlProvider messages={messages} locale={locale}>
{props.children}
</IntlProvider>
</Context.Provider>
);
}
export default Wrapper;
Что делает этот Wrapper? Вы не всегда можете жестко указать язык пользователя в своем приложении, и он не всегда будет нравиться пользователю, когда приложение отображается только на его предпочтительном языке. Пользователь должен иметь возможность при необходимости изменить местоположение. Вот почему мы представляем класс Wrapper.
const Context = React.createContext();
React.createContext создает объект Context. Здесь происходит то, что когда React визуализирует компонент, который подписывается на этот объект, он считывает текущее значение контекста в ближайшем подходящем Provider чуть выше него. Вы также можете указать здесь значение по умолчанию как «en», но это не обязательно, поскольку мы используем языковой навигатор.
const Wrapper = (props) => {
const [locale, setLocale] = useState(local);
const [messages, setMessages] = useState(lang);
function selectLanguage(e) {
const newLocale = e.target.value;
setLocale(newLocale);
if (newLocale === 'en') {
setMessages(English);
} else {
if (newLocale === 'ru'){
setMessages(Russian);
} else {
setMessages(Arabic);
}
}
}
Вы слышали о хуках в React? Они были новым дополнением в React v16.8. Что они делают, так это позволяют разработчикам использовать состояние и некоторые другие функции в React без необходимости писать класс. useState — это базовый хук. Состояние использования возвращает значение с сохранением состояния, а также функцию, которую можно использовать для его обновления. Вот основной синтаксис для useState:
const [state, setState] = useState(initialState);
При первой визуализации состояние, которое отображается, совпадает со значением, переданным в качестве первого аргумента: intialState. Функция selectLanguage заботится о переключении между языками. Он содержит простую функцию if / else и устанавливает язык, проверяя значение newLocale. Этот метод if / else возможен, когда с вашим приложением связано только небольшое количество языков. Однако это не так, когда у вас много языков и вам, возможно, придется подумать о лучшем решении.
<Context.Provider value = {{locale, selectLanguage}}>
<IntlProvider messages={messages} locale={locale}>
{props.children}
</IntlProvider>
</Context.Provider>
Теперь каждый объект Context содержит компонент Provider React. Это позволяет использовать компоненты для подписки на любые изменения контекста. Как я уже упоминал, createContext возвращает Provider. Он также предоставляет потребительский компонент.
Отрисовка переключателя языка
Компонент поставщика обертывает компоненты в дереве, которому требуется доступ к значениям контекста. Вы видите, что Context.Provider представляет собой лишь тонкую оболочку для компонента Provider? Здесь значение контекста передается поставщику с использованием значения prop, а затем отображаются дочерние элементы Context.Provider.
App.js
import React, {useContext} from 'react';
import logo from './logo.svg';
import './App.css';
import {FormattedMessage, FormattedDate} from 'react-intl';
import {Context} from "./components/Wrapper";
function App(props) {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
<FormattedMessage
id = "app.header"
defaultMessage="Edit the files and save to reload"
values = {{fileName: 'src/App.js', code: (word)=> <strong>{word}</strong>}}
/>
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
<FormattedMessage
id = "app.content"
defaultMessage="Learn React"
/>
</a>
<FormattedMessage
id = "app.channel.plug"
defaultMessage="Tutorial brought to you by Lokalise"
values = {{blogName: "Lokalise"}}
/>
<br/>
<FormattedDate
value={props.date}
year = 'numeric'
month= 'long'
day = 'numeric'
weekday = 'long'
/>
</header>
</div>
);
}
export default App;
Props обозначает свойства в React, и они используются для передачи данных от одного компонента другому. Важно отметить, что props доступны только для чтения, и данные, генерируемые родительским элементом, не должны изменяться в дочерних компонентах.
Теперь посмотрим, что такое Context. Он предоставляет способ передачи данных через дерево компонентов, поэтому ручная передача свойств не требуется на каждом уровне.
Если вы уже знакомы с React, возможно, вы знаете, что данные передаются по принципу «родитель-потомок» через свойства. Однако это не всегда возможный выбор. Например, предпочтение локали требуется для многих компонентов в дополнение к глобальному в нашем приложении. Следовательно, нам нужно использовать Context, поскольку он обеспечивает способ обмена такими значениями между компонентами, не требуя от нас передачи свойств вниз на каждом уровне дерева компонентов.
Index.js:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import {IntlProvider} from 'react-intl';
import Wrapper from "./components/Wrapper";
ReactDOM.render(
<Wrapper>
<App date = {Date.now()}/>
</Wrapper>,
document.getElementById('root')
);
serviceWorker.unregister();
Выход
Теперь, чтобы использовать созданный контекст, мы должны экспортировать его, чтобы другие модули могли его импортировать:
export const Context = React.createContext();
App.js:
import React, {useContext} from 'react';
import {Context} from "./components/Wrapper";
function App(props) {
const context = useContext(Context);
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<select value = {context.locale} onChange={context.selectLanguage}>
<option value= 'en'>English</option>
<option value= 'ru'>Russian</option>
<option value= 'ar'>Arabic</option>
</select>
</header>
</div>
);
}
export default App;
В функции возврата мы написали код, включающий раскрывающееся меню, которое будет изменяться функцией selectLanguage, которая импортируется с контекстом.
Форматирование даты и времени в React i18n
FormattedDate
Я уже показал вам, как локализовать дату. Но здесь мы обсудим основной синтаксис и то, как это происходит. Компонент FormattedDate заботится об изменении даты в соответствии с выбранной локалью. Когда вы вставляете дату, вы должны определить, какие форматы вы хотите для года, месяца, дня и дня недели.
<FormattedDate
value={props.date}
year = 'numeric'
month= 'long'
day = 'numeric'
weekday = 'long'
/>
Формат «числовой» указывает на то, что вы хотите указать год и день в числовом формате, а «длинный» в формате «месяц и день недели» означает, что вы хотите, чтобы месяц и день недели были в строке, причем оба слова были написаны полностью.
FormattedTime
Компонент FormattedTime может форматировать время в зависимости от локали, как и компонент FormattedDate.
<FormattedTime
value={new Date()}
hour="numeric"
minute="numeric"
second="numeric"
timeZoneName="long"
/>
Форматирование чисел и валют в React i18n
FormattedNumber
Если вы читали статьи по интернационализации и локализации, возможно, вы знаете, что в разных странах используются разные способы представления чисел. Например, в США для разделения длинных чисел на группы по три используются запятые.
Компонент FormattedNumber предоставляется response-intl для форматирования чисел и десятичных дробей в зависимости от локали.
<FormattedNumber
value={10000}
/>
Еще одно применение этого — то, что его также можно использовать для форматирования валют. См. Пример ниже:
<FormattedNumber
value={20.42}
style="currency"
currencyDisplay="symbol"
currency="USD"
/>
Множественное число React i18n в React-intl
FormattedPlural
Это еще один компонент, предоставляемый библиотекой react-intl. FormattedPlural можно использовать для форматирования множественного числа и количества в соответствии с локалью. Вы можете изменить файл en.json, добавив следующие строки:
{
"app.plural": "{amount, plural, =0 {no languages} one {# one language} few {# several languages} many {# lots of languages} other {# wrong format}}"
}
Затем, чтобы использовать это в нашем приложении, нам нужно включить следующий код в файл App.js:
<FormattedPlural
id = "app.plural"
defaultMessage="{amount, plural, =0 {no languages} one {# one language} few {# several languages} many {# lots of languages} other {# wrong format}}"
values = {{amount: 3}}
/>
Финальные мысли
Когда дело доходит до React i18n, лучшим решением или общим выбором является библиотека react-intl. Наличие 12,3 тысяч звезд на GitHub сделало его намного более популярным, чем другие библиотеки.
Однако, как и любая другая библиотека React i18n, эта знаменитая библиотека также имеет некоторые недостатки. Одна из них заключается в том, что вы не можете использовать react-intl для нереагирующих компонентов. Он требует, чтобы компонент верхнего уровня внедрил контекст в дочерние элементы. Вот почему некоторые люди переходят к библиотеке react-intl-universal в качестве решения.