Пишемо мультимовний додаток на React Native

Пишемо мультимовний додаток на React Native

Локалізація продукції є дуже важливою для міжнародних компаній, які освоюють нові для себе країни та регіони. Аналогічно локалізація потрібна і для мобільних додатків. Якщо розробник розпочинає міжнародну експансію, важливо дати користувачам з іншої країни можливість працювати з інтерфейсом рідною мовою. У цій статті ми створимо програму React Native, використовуючи пакет react-native-localize.

Skillbox рекомендує: Освітній онлайн-курс «Професія Java-розробник».
Нагадуємо: для всіх читачів "Хабра" - знижка 10 000 рублів при записі на будь-який курс Skillbox за промокодом "Хабр".

Інструменти та навички

Для розуміння цієї статті потрібні базові навички роботи з React Native. Для ознайомлення з налаштуваннями робочої машини можна скористатися офіційною інструкцією.

Нам знадобляться такі версії програмних інструментів:

  • Вузол v10.15.0
  • npm 6.4.1
  • пряжа 1.16.0
  • react-native 0.59.9
  • react-native-localize 1.1.3
  • i18n-js 3.3.0

починаємо

Ми створимо додаток, який буде підтримувати англійську, французьку та арабську мови. Спершу створюємо новий проект, використовуючи 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) – це текст, який потрібно показувати користувачеві.

Англійська мова:

{ "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

Виглядати це буде приблизно так:

Пишемо мультимовний додаток на React Native

Тепер можна спробувати змінити мову на французьку, запустивши потім програму.

Пишемо мультимовний додаток на React Native

З арабською мовою проробляємо те саме, різниці немає.

Поки що все йде добре.

Але що станеться, якщо вибрати випадкову мову, перекладу якої немає у додатку?

Виявляється, завдання findBestLanguage - надання оптимального з усіх доступних перекладів. В результаті буде відображено мову, яка була встановлена ​​за умовчанням.

Йдеться про налаштування телефону. Так, наприклад, в емуляторі iOS можна переглянути порядок мов.

Пишемо мультимовний додаток на React Native

Якщо вибрана мова не є бажаною, findBestAvailableLanguage повертає undefined, так що відображається та мова, яка встановлена ​​за замовчуванням.

Бонус

React-native-localize має API, яке надає доступ до великої кількості мовних елементів. Перед тим, як розпочати роботу, варто ознайомитись із документацією.

Висновки

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

Вихідний код проекту знаходиться тут.

Skillbox рекомендує:

Джерело: habr.com

Додати коментар або відгук