- PVSM.RU - https://www.pvsm.ru -
Локализация продукции очень важна для международных компаний, осваивающих новые для себя страны и регионы. Аналогично локализация нужна и мобильным приложениям. Если разработчик начинает международную экспансию, важно дать пользователям из другой страны возможность работать с интерфейсом на родном языке. В этой статье мы создадим приложение React Native, используя пакет react-native-localize [1].
Skillbox рекомендует: Образовательный онлайн-курс «Профессия Java-разработчик» [2].
Напоминаем: для всех читателей «Хабра» — скидка 10 000 рублей при записи на любой курс Skillbox по промокоду «Хабр».
Для понимания этой статьи нужны базовые навыки работы с React Native. Для ознакомления с настройками рабочей машины можно воспользоваться официальной инструкцией [3].
Нам понадобятся вот такие версии программных инструментов:
Мы создадим приложение, которое будет поддерживать английский, французский и арабский языки. Сначала создаем новый проект, используя react-native-cli. Для этого в терминале нужно набрать вот что:
$ react-native init multiLanguage
$ cd multiLanguage
Добавляем необходимые библиотеки
Первым делом нужно установить react-native-localize, набрав следующее:
$ yarn add react-native-localize
Если в процессе установки возникают проблемы, стоит изучить мануал по установке [4].
Библиотека react-native-localize дает разработчику доступ к мультиязычным функциям. Но ей нужна еще одна библиотека — i18n.
В статье описывается использование I18n.js [5] для того, чтобы обеспечить перевод в JavaScript.
$ yarn add i18n-js
Ну а поскольку i18n-js не предоставляет кэширования или мемоизации, я предлагаю использовать для этого lodash.memoize:
$ yarn add lodash.memoize
Работа с переводами
Для того, чтобы приложение умело работать и с другими языками, сначала нужно создать каталог translations внутри src, потом — три файла JSON, для каждого из языков.
1. en.json для английского;
2. fr.json для французского;
3. ar.json для арабского.
Эти файлы содержат объекты JSON с ключами и значениями. Ключ будет один и тот же для каждого языка. Он используется приложением для отображения текстовой информации.
Значение (value) — это текст, который нужно показывать пользователю.
Английский язык:
{ «hello»: «Hello World!»}
Французский
{ «hello»: «Salut le Monde!»}
Арабский
{ «hello»: "أهلاً بالعالم"}
Аналогичным образом можно добавлять и другие языки.
На этом этапе нужно открыть файл App.js и добавить в него импорт:
import React from "react";
import * as RNLocalize from "react-native-localize";
import i18n from "i18n-js";
import memoize from "lodash.memoize"; // Use for caching/memoize for better performance
import {
I18nManager,
SafeAreaView,
ScrollView,
StyleSheet,
Text,
View
} from "react-native";
После этого добавляются вспомогательные функции и константы, которые пригодятся впоследствии.
const translationGetters = {
// lazy requires (metro bundler does not support symlinks)
ar: () => require("./src/translations/ar.json"),
en: () => require("./src/translations/en.json"),
fr: () => require("./src/translations/fr.json")
};
const translate = memoize(
(key, config) => i18n.t(key, config),
(key, config) => (config ? key + JSON.stringify(config) : key)
);
const setI18nConfig = () => {
// fallback if no available language fits
const fallback = { languageTag: "en", isRTL: false };
const { languageTag, isRTL } =
RNLocalize.findBestAvailableLanguage(Object.keys(translationGetters)) ||
fallback;
// clear translation cache
translate.cache.clear();
// update layout direction
I18nManager.forceRTL(isRTL);
// set i18n-js config
i18n.translations = { [languageTag]: translationGetters[languageTag]() };
i18n.locale = languageTag;
};
Ну а теперь создадим компонент класса App:
export default class App extends React.Component {
constructor(props) {
super(props);
setI18nConfig(); // set initial config
}
componentDidMount() {
RNLocalize.addEventListener("change", this.handleLocalizationChange);
}
componentWillUnmount() {
RNLocalize.removeEventListener("change", this.handleLocalizationChange);
}
handleLocalizationChange = () => {
setI18nConfig();
this.forceUpdate();
};
render() {
return (
<SafeAreaView style={styles.safeArea}>
<Text style={styles.value}>{translate("hello")}</Text>
</SafeAreaView>
);
}
}
const styles = StyleSheet.create({
safeArea: {
backgroundColor: "white",
flex: 1,
alignItems: "center",
justifyContent: "center"
},
value: {
fontSize: 18
}
});
Первый элемент — setI18nConfig() — устанавливает начальную конфигурацию.
Затем в componentDidMount() нужно добавить прослушивание событий, этот элемент будет отслеживать обновления и вызывать handleLocalizationChange() в том случае, когда они происходят.
Метод handleLocalizationChange() активизирует setI18nConfig() и forceUpdate(). Это необходимо для устройств на Android, так как компонент должен быть отрендерен, чтобы изменения стали заметными.
Затем нужно убрать прослушивание из метода componentWillUnmount().
Наконец, в render() возвращается hello путем использования translate() и добавления в него параметра key. После этих действий приложение сможет «понимать», какой язык нужен, и показывать сообщения именно на нем.
Теперь самое время проверить, как работает перевод.
Сначала запускаем приложение в симуляторе или эмуляторе, набирая
$ react-native run-ios
$ react-native run-android
Выглядеть это будет примерно так:
Теперь можно попробовать сменить язык на французский, запустив затем приложение.
С арабским языком проделываем то же самое, разницы нет.
Пока все идет хорошо.
Но что произойдет, если выбрать случайный язык, перевода которого нет в приложении?
Оказывается, задача findBestLanguage — предоставление оптимального из всех доступных перевода. В результате будет отображаться язык, который был установлен по умолчанию.
Речь идет о настройках телефона. Так, например, в эмуляторе iOS можно посмотреть порядок языков.
Если выбранный язык не является предпочитаемым, findBestAvailableLanguage возвращает undefined, так что показывается тот язык, который установлен по умолчанию.
У react-native-localize есть API, которое предоставляет доступ к большому количеству языковых элементов. Перед тем, как начать работу, стоит ознакомиться с документацией [6].
Приложение можно сделать мультиязычным без особых проблем. React-native-localize — отличный вариант, который позволяет расширить круг пользователей приложения.
Исходный код проекта находится здесь [7].
Skillbox рекомендует:
- Двухлетний практический курс «Я — веб-разработчик PRO» [8].
- Онлайн-курс «С#-разработчик с нуля» [9].
- Практический годовой курс «PHP-разработчик с 0 до PRO» [10].
Автор: fokus-lop
Источник [11]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/programmirovanie/323708
Ссылки в тексте:
[1] react-native-localize: https://github.com/react-native-community/react-native-localize
[2] «Профессия Java-разработчик»: https://skillbox.ru/java/?utm_source=skillbox.media&utm_medium=habr.com&utm_campaign=JAVDEV&utm_content=articles&utm_term=reactnative
[3] воспользоваться официальной инструкцией: https://facebook.github.io/react-native/docs/0.59/getting-started
[4] стоит изучить мануал по установке: https://github.com/react-native-community/react-native-localize#setup
[5] I18n.js: https://github.com/fnando/i18n-js
[6] стоит ознакомиться с документацией: https://github.com/react-native-community/react-native-localize#api
[7] находится здесь: https://github.com/vikrantnegi/react-native-multi-language-app
[8] «Я — веб-разработчик PRO»: https://iamwebdev.skillbox.ru/?utm_source=skillbox.media&utm_medium=habr.com&utm_campaign=WEBDEVPRO&utm_content=articles&utm_term=reactnative
[9] «С#-разработчик с нуля»: https://skillbox.ru/c-sharp/?utm_source=skillbox.media&utm_medium=habr.com&utm_campaign=CSHDEV&utm_content=articles&utm_term=reactnative
[10] «PHP-разработчик с 0 до PRO»: https://skillbox.ru/php/?utm_source=skillbox.media&utm_medium=habr.com&utm_campaign=PHPDEV&utm_content=articles&utm_term=reactnative
[11] Источник: https://habr.com/ru/post/459741/?utm_campaign=459741&utm_source=habrahabr&utm_medium=rss
Нажмите здесь для печати.