Начало работы с интернационализацией (i18n) в React

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

В этой статье вы узнаете, как локализовать приложение React.

1. Установите модуль i18n

Чтобы справиться с интернационализацией в вашем приложении, мы собираемся использовать модуль i18n-реагировать. Этот модуль предлагает простую обработку интернационализации и экстернализации текста. Установите модуль с помощью следующей команды в командной строке:

npm install i18n-react --save

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

2. Использование модуля

Логика работы этого модуля проста:

  1. Требуйте или импортируйте модуль в верхней части вашего приложения (Основной компонент).
  2. Добавьте тексты вашего приложения вверху вашего приложения (Основной компонент). Это действие не обязательно должно выполняться из основного компонента, но также и из дочерних компонентов.
  3. Используйте модуль и переводите метки в другие компоненты.

Система перевода работает с объектом, который содержит некоторые свойства и строки в качестве значений (эти строки содержат метки на одном языке).

Предоставить текст

Вы должны предоставить вначале текст, который будет переведен с setTexts метод. Очевидно, что модуль должен быть импортирован или необходим в соответствии с используемой версией EcmaScript:

/* ES6 & TS */
import T from 'i18n-react';
/* commonJS */
var T = require('i18n-react').default;
/* when using UMD version w/o modules */
var T = window['i18n-react'].default;
// Set some texts
T.setTexts({
welcome: "Bienvenido {username}!",
buttons: {
exit: "Salir",
start: "Iniciar"
}
});

Обратите внимание, что i18n поддерживает интерполяцию для динамического изменения некоторого значения в переводе (поскольку не все языки имеют одинаковую структуру). Одна из фундаментальных особенностей реализации модуля интернационализации состоит в том, что он не должен обеспечивать поддержку только для простых переводов строк в строку, но должен поддерживать множественное число. i18n-реакция поддерживает другую локализацию, плюрализм, поддержку формального и неформального, пожалуйста, прочитайте больше об этих функциях здесь.

Этот метод, вероятно, будет инициализирован один раз и, вероятно, будет выполнен в точке входа вашего приложения.

Идет перевод

Как только появятся доступные тексты, их можно использовать для перевода меток в вашем приложении с помощью того же модуля. Вы можете использовать метод одиночного перевода, чтобы получить метку с помощью ключа или визуализировать элементы другого типа, например a, p или же span элементы:

import React from 'react';
import {render} from 'react-dom';
// Our custom react component with some elements inside
import Main from './Main';
// Import the translation module
import T from 'i18n-react';
// link
// Text
// Paragraph
// Span

/* Or translate without using an Element with the T.translate method */
{T.translate("welcome", { username: "Bruce Wayne" })}

По умолчанию, если перевод для указанного ключа отсутствует, возвращается сам ключ, чтобы помочь вам найти отсутствующий перевод. Такое поведение может быть дополнено путем предоставления notFound свойство в параметрах или объекте MDText.

пример

У нас есть следующее app.js который инициализирует приложение React. Здесь мы собираемся использовать модуль i18n, и мы предоставим объект, который содержит текст некоторых кнопок на испанском языке. Они будут объявлены при инициализации вашего приложения:

import React from 'react';
import {render} from 'react-dom';
// Our custom react component with some elements inside
import Main from './Main';
// Import the translation module
import T from 'i18n-react';
// Add the texts for your APP
T.setTexts({
labels: {
accept: "Aceptar",
decline: "Declinar"
}
});
// Render the Main app react component into the app div.
// For more details see: https://facebook.github.io/react/docs/top-level-api.html#react.render
render(, document.getElementById('app'));

Теперь, когда у нас есть несколько меток, мы можем использовать их из наших компонентов. В нашем главном компоненте мы просто добавим 2 кнопки, которые вызывают оповещение в соответствии с выбранным элементом, метки этих кнопок мы получим через модуль i18n:

import React from 'react';
// Some button component example
import FlatButton from 'material-ui/FlatButton';
// Import Internationalization
import T from 'i18n-react';
export default class Main extends React.Component {
constructor(props) {
super(props);
this.state = {
};
}
actionAccepted = () => {
alert("You declined this");
}
actionDeclined = () => {
alert("You declined this");
}
render() {
return (

);
}
}

Обратите внимание, что текстовый параметр или первый аргумент функции translate ожидает имя объекта в стиле «Javascript style» (структура объекта). В предыдущем примере неудивительно, что

Пример кнопки React Испанский

Как видите, единственное, о чем вам нужно беспокоиться, это как предоставить ярлыки. Обратите внимание, что мы делаем это только для испанского языка, поэтому, если у вас есть другой объект для разных языков, вам нужно выполнить setTexts метод с метками нового языка в качестве первого аргумента.

Рекомендуется хранить переводы во внешних файлах (вместо того, чтобы смешивать их непосредственно в вашем коде), таких как JSON или YAML, а затем снова требовать их в вашем коде в объектном формате.

3. Загрузка данных локали из файлов

Как упоминалось ранее, предпочтительно сохранять локали в специальных файлах, таких как JSON, что упрощает администрирование меток для разных языков в вашем приложении. Этот шаг полностью зависит от вас, как вы извлекаете языковой стандарт из браузера, как вы храните языковые стандарты в файлах и т. Д. Однако мы покажем вам, как это работает, и его легко реализовать.

Для начала нам нужно знать, как мы собираемся хранить локали во внешних файлах, мы будем использовать файлы JSON. Например, метки на испанском языке будут храниться в файле JSON (es.json) со следующим содержанием:

{
"labels": {
"accept": "Aceptar",
"decline": "Declinar"
}
}

Затем, когда у вас есть ярлыки для любого языка, вам нужно определить в браузере, какой язык использует пользователь в данный момент. Это сильно зависит от вашего проекта, вы можете сохранить этот язык в базе данных или что-то в этом роде, но для объяснения этого мы будем использовать язык браузера. Это будет получено с помощью следующего кода:

var language = (navigator.languages && navigator.languages[0]) || navigator.language || navigator.userLanguage;
// language would be something like es-ES or es_ES
// However we store our files with format es.json or en.json
// therefore retrieve only the first 2 digits
if (language.length > 2) {
language = language.split("-")[0];
language = language.split("_")[0];
}
// language would be now only "es"

Поскольку файлы перевода нашего проекта будут очень простыми, они будут иметь структуру имени (всего 2 цифры): es, de, en, ru, jp, zh и т. Д. Мы будем использовать ее для запроса правильных файлов перевода.

В зависимости от того, как вы работаете, а также от размера (и количества) локалей вашего приложения, вы можете загружать локали из статических файлов JSON.

A. Запрос файлов локали

Как вы наверняка знаете, вы можете использовать любую стороннюю библиотеку для запроса файлов в React. Вы можете использовать встроенную в браузер реализацию fetch (рекомендуется также включать полифилл как WHATWG-выборки для устаревших браузеров) или используйте специальные библиотеки, такие как Вардар (или же JQuery AJAX, здесь никто не судит)

Логика заставить это работать довольно просто, как вы знаете, setTexts Метод ожидает объект, поэтому это единственное, о чем вам нужно беспокоиться, предоставьте объекту структуру, необходимую для интернационализации, и вы готовы к работе. В следующем примере (мы собираемся использовать метод getJSON jQuery ajax, который, вероятно, знает каждый разработчик), загружает файл JSON и преобразует его в объект Javascript, который автоматически доставляется в качестве первого аргумента в setTexts метод библиотеки интернационализации, который мы только что установили:

$.getJSON("path-to/locales/"+ language +".json", function( data ) {
T.setTexts(data);
});

Обратите внимание, что вам нужно будет обновить компонент после обновления локали. Эта функция может быть вызвана из любого элемента формы, который изменяет язык вашего приложения, например, раскрывающийся список, выбор и т. Д. Вы можете локально хранить уже используемые локали (используя localStorage или webStorage), чтобы предотвратить выполнение необязательного запроса к серверу.

B. с веб-загрузчиком

В случае, если ваше приложение использует веб-пакет, и ваши языковые файлы не такие большие (всего 3 языка, и они не увеличивают размер файла вашего app.min.js радикально) или работает автономно (не беспокойтесь о app.min.js размер файла) например, приложение React, которое работает под Electron или Cordova, вы можете добавить файлы локали в формате json в ваше приложение, используя специальный загрузчик для файлов json (JSON-погрузчик).

Заметка

Начиная с веб-пакета V2, файлы JSON будут работать по умолчанию. Вы все еще можете использовать это, если вы используете пользовательское расширение файла.

Установите модуль json-загрузчика с помощью следующей команды:

npm install --save-dev json-loader

После установки модуля вам необходимо изменить webpack-.config.js (производство и разработка) файлов и добавить пользовательский загрузчик:

{
test: /\.json$/,
loader: "json",
include: "path/to/locales/json-files"
}

Сделав это, вы сможете требовать локали и включать их в файл сборки.

Заметка

Даже если ваше приложение использует много языков, рекомендуется использовать этот метод хотя бы с локалью по умолчанию (например, английской). Таким образом, ваша первая страница уже будет содержать основные сообщения, которые ей требуются, избегая запроса GET с метками по умолчанию, пока пользователь явно не изменит локаль:

T.setTexts(require(`!json!./path-to-locales/${language}.json`));

Обратите внимание, что с веб-пакетом необходимо добавить !json! строка к URL, чтобы заставить это работать должным образом. Вы можете создать собственный метод, который охватывает все предыдущие шаги

Обновление ярлыков динамически

Если вы уже реализовали локализацию с помощью этого руководства в своем проекте, вы могли заметить, что если вы обновите тексты с помощью T.setTexts по-видимому, ничего не происходит (хотя это действительно происходит, ярлыки в вашем проекте не обновляются, они по-прежнему содержат то же содержимое, что и в первый раз, когда вы выполнили setTexts). Позвольте мне сказать вам, что это поведение не ошибка. В настоящее время нет модулей, которые автоматически обновляют элементы динамически в каждом компоненте. Поэтому вам необходимо выяснить (в соответствии с тем, как вы работаете с React, как обычно, когда кто-то меняет язык приложения, его следует перезапустить или перерисовать в случае React), как динамически обновлять их, например, задавать локали в состоянии компонента.

Если вы не хотите тратить на это время, есть другие простые решения, которые могут работать в соответствии с архитектурой вашего проекта, например просто перерисовать компонент может добиться цели для некоторых проектов:

// The app starts normally with english locale ...
// Then set it to spanish
T.setTexts(require('!json!./locales/es.json'));
// Render component again ... voila in Spanish
this.forceUpdate();
// Wait 5 seconds ...
// Now change it to German
T.setTexts(require('!json!./locales/de.json'));
// Render component again ... voila in german
this.forceUpdate();

Если вы выбираете легкий путь, узнайте больше о том, как перерисовать компонент React, потому что есть дискуссия о том, как компонент должен быть перерисован. По-видимому forceUpdate его следует избегать, поскольку он отличается от мышления React, поэтому вы можете использовать другой способ, например, сброс состояния из компонента:

// The app starts normally with english locale ...
// Then set it to spanish
T.setTexts(require('!json!./locales/es.json'));
// Render component again ... voila in Spanish
this.setState(this.state);
// Wait 5 seconds ...
// Now change it to German
T.setTexts(require('!json!./locales/de.json'));
// Render component again ... voila in german
this.setState(this.state);

Обратите внимание, что обновление повлияет на один компонент (полезно только в том случае, если вы используете приложение с реагирующим маршрутизатором или что-то подобное).

Ссылка на основную публикацию
Adblock
detector