Scrierea unei aplicații multilingve în React Native

Scrierea unei aplicații multilingve în React Native

Локализация продукции очень важна для международных компаний, осваивающих новые для себя страны и регионы. Аналогично локализация нужна и мобильным приложениям. Если разработчик начинает международную экспансию, важно дать пользователям из другой страны возможность работать с интерфейсом на родном языке. В этой статье мы создадим приложение React Native, используя пакет react-native-localize.

Skillbox recomandă: Curs educativ online „Profesie Dezvoltator Java”.
Amintim: pentru toți cititorii „Habr” - o reducere de 10 de ruble la înscrierea la orice curs Skillbox folosind codul promoțional „Habr”.

Инструменты и навыки

Для понимания этой статьи нужны базовые навыки работы с React Native. Для ознакомления с настройками рабочей машины можно воспользоваться официальной инструкцией.

Нам понадобятся вот такие версии программных инструментов:

  • Node v10.15.0
  • npm 6.4.1
  • yarn 1.16.0
  • react-native 0.59.9
  • react-native-localize 1.1.3
  • i18n-js 3.3.0

Noțiuni de bază

Мы создадим приложение, которое будет поддерживать английский, французский и арабский языки. Сначала создаем новый проект, используя react-native-cli. Для этого в терминале нужно набрать вот что:

$ react-native init multiLanguage
$ cd multiLanguage

Добавляем необходимые библиотеки

Первым делом нужно установить react-native-localize, набрав следующее:
$ yarn add react-native-localize

Если в процессе установки возникают проблемы, стоит изучить мануал по установке.

Библиотека react-native-localize дает разработчику доступ к мультиязычным функциям. Но ей нужна еще одна библиотека — i18n.

В статье описывается использование I18n.js для того, чтобы обеспечить перевод в 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) — это текст, который нужно показывать пользователю.

Engleză:

{ «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. После этих действий приложение сможет «понимать», какой язык нужен, и показывать сообщения именно на нем.

Lansarea aplicației

Теперь самое время проверить, как работает перевод.

Сначала запускаем приложение в симуляторе или эмуляторе, набирая

$ react-native run-ios
$ react-native run-android

Выглядеть это будет примерно так:

Scrierea unei aplicații multilingve în React Native

Теперь можно попробовать сменить язык на французский, запустив затем приложение.

Scrierea unei aplicații multilingve în React Native

С арабским языком проделываем то же самое, разницы нет.

Пока все идет хорошо.

Но что произойдет, если выбрать случайный язык, перевода которого нет в приложении?

Оказывается, задача findBestLanguage — предоставление оптимального из всех доступных перевода. В результате будет отображаться язык, который был установлен по умолчанию.

Речь идет о настройках телефона. Так, например, в эмуляторе iOS можно посмотреть порядок языков.

Scrierea unei aplicații multilingve în React Native

Если выбранный язык не является предпочитаемым, findBestAvailableLanguage возвращает undefined, так что показывается тот язык, который установлен по умолчанию.

primă

У react-native-localize есть API, которое предоставляет доступ к большому количеству языковых элементов. Перед тем, как начать работу, стоит ознакомиться с документацией.

Constatări

Приложение можно сделать мультиязычным без особых проблем. React-native-localize — отличный вариант, который позволяет расширить круг пользователей приложения.

Codul sursă al proiectului este aici.

Skillbox recomandă:

Sursa: www.habr.com

Adauga un comentariu