ื›ืชื™ื‘ืช ืืคืœื™ืงืฆื™ื” ืจื‘ ืœืฉื•ื ื™ืช ื‘-React Native

ื›ืชื™ื‘ืช ืืคืœื™ืงืฆื™ื” ืจื‘ ืœืฉื•ื ื™ืช ื‘-React Native

ืœื•ืงืœื™ื–ืฆื™ื” ืฉืœ ืžื•ืฆืจื™ื ื—ืฉื•ื‘ื” ืžืื•ื“ ืขื‘ื•ืจ ื—ื‘ืจื•ืช ื‘ื™ื ืœืื•ืžื™ื•ืช ื”ื‘ื•ื“ืงื•ืช ืžื“ื™ื ื•ืช ื•ืื–ื•ืจื™ื ื—ื“ืฉื™ื. ื‘ืื•ืคืŸ ื“ื•ืžื”, ื ื“ืจืฉืช ืœื•ืงืœื™ื–ืฆื™ื” ืขื‘ื•ืจ ื™ื™ืฉื•ืžื™ื ื ื™ื™ื“ื™ื. ืื ืžืคืชื— ืžืชื—ื™ืœ ื‘ื”ืชืจื—ื‘ื•ืช ื‘ื™ื ืœืื•ืžื™ืช, ื—ืฉื•ื‘ ืœืชืช ืœืžืฉืชืžืฉื™ื ืžืžื“ื™ื ื” ืื—ืจืช ืืช ื”ืืคืฉืจื•ืช ืœืขื‘ื•ื“ ืขื ื”ืžืžืฉืง ื‘ืฉืคืช ื”ืื ืฉืœื”ื. ื‘ืžืืžืจ ื–ื”, ื ื™ืฆื•ืจ ื™ื™ืฉื•ื React Native ื‘ืืžืฆืขื•ืช ื”ื—ื‘ื™ืœื” ืœื”ื’ื™ื‘-ื™ืœื™ื“-ืœื•ืงืœื™ื–.

Skillbox ืžืžืœื™ืฆื”: ืงื•ืจืก ื—ื™ื ื•ื›ื™ ืžืงื•ื•ืŸ "ืžืงืฆื•ืขื™ ืžืคืชื— ื’'ืื•ื•ื”".
ืื ื• ืžื–ื›ื™ืจื™ื: ืœื›ืœ ืงื•ืจืื™ Habr - ื”ื ื—ื” ืฉืœ 10 ืจื•ื‘ืœ ื‘ืขืช ื”ืจืฉืžื” ืœื›ืœ ืงื•ืจืก Skillbox ื‘ืืžืฆืขื•ืช ืงื•ื“ ื”ื”ื˜ื‘ื” ืฉืœ Habr.

ื›ืœื™ื ื•ืžื™ื•ืžื ื•ื™ื•ืช

ื›ื“ื™ ืœื”ื‘ื™ืŸ ืืช ื”ืžืืžืจ ื”ื–ื”, ืืชื” ืฆืจื™ืš ืžื™ื•ืžื ื•ื™ื•ืช ื‘ืกื™ืกื™ื•ืช ื‘ืขื‘ื•ื“ื” ืขื 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 ื”ื•ืกืฃ react-native-localize

ืื ืžืชืจื—ืฉื•ืช ื‘ืขื™ื•ืช ื‘ืžื”ืœืš ืชื”ืœื™ืš ื”ื”ืชืงื ื”, ื›ื“ืื™ ืœืงืจื•ื ืืช ืžื“ืจื™ืš ื”ื”ืชืงื ื”.

ืกืคืจื™ื™ืช react-native-localize ืžืขื ื™ืงื” ืœืžืคืชื— ื’ื™ืฉื” ืœืชื›ื•ื ื•ืช ืจื‘ ืœืฉื•ื ื™ื•ืช. ืื‘ืœ ื”ื™ื ืฆืจื™ื›ื” ืขื•ื“ ืกืคืจื™ื™ื” ืื—ืช - i18n.

ืžืืžืจ ื–ื” ืžืชืืจ ืืช ื”ืฉื™ืžื•ืฉ I18n.js ืขืœ ืžื ืช ืœืกืคืง ืชืจื’ื•ื ืœ-JavaScript.

$ yarn add i18n-js

ื•ื‘ื›ืŸ, ืžื›ื™ื•ื•ืŸ ืฉ-i18n-js ืื™ื ื• ืžืกืคืง ืื—ืกื•ืŸ ื‘ืžื˜ืžื•ืŸ ืื• ืฉื™ื ื•ืŸ, ืื ื™ ืžืฆื™ืข ืœื”ืฉืชืžืฉ ื‘-lodash.memoize ืขื‘ื•ืจ ื–ื”:

$ yarn ื”ื•ืกืฃ lodash.memoize

ืขื‘ื•ื“ื” ืขื ืชืจื’ื•ืžื™ื

ื›ื“ื™ ืฉื”ืืคืœื™ืงืฆื™ื” ืชื•ื›ืœ ืœืขื‘ื•ื“ ืขื ืฉืคื•ืช ืื—ืจื•ืช, ืชื—ื™ืœื” ืขืœื™ืš ืœื™ืฆื•ืจ ืกืคืจื™ื™ืช ืชืจื’ื•ืžื™ื ื‘ืชื•ืš src, ื•ืœืื—ืจ ืžื›ืŸ ืฉืœื•ืฉื” ืงื‘ืฆื™ JSON ืœื›ืœ ืฉืคื”.

1. en.json ืœืื ื’ืœื™ืช;

2. fr.json ืœืฆืจืคืชื™ืช;

3. ar.json ืœืขืจื‘ื™ืช.

ืงื‘ืฆื™ื ืืœื” ืžื›ื™ืœื™ื ืื•ื‘ื™ื™ืงื˜ื™ JSON ืขื ืžืคืชื—ื•ืช ื•ืขืจื›ื™ื. ื”ืžืคืชื— ื™ื”ื™ื” ื–ื”ื” ืขื‘ื•ืจ ื›ืœ ืฉืคื”. ื”ื•ื ืžืฉืžืฉ ืืช ื”ืืคืœื™ืงืฆื™ื” ืœื”ืฆื’ืช ืžื™ื“ืข ื˜ืงืกื˜.

ืขืจืš ื”ื•ื ื”ื˜ืงืกื˜ ืฉืฆืจื™ืš ืœื”ืจืื•ืช ืœืžืฉืชืžืฉ.

ืื ื’ืœื™ืช:

{"hello": "ืฉืœื•ื ืขื•ืœื!"}

ะคั€ะฐะฝั†ัƒะทัะบะธะน

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

ื•ื‘ื›ืŸ, ืขื›ืฉื™ื• ื‘ื•ืื• ื ื™ืฆื•ืจ ืจื›ื™ื‘ ืฉืœ ืžื—ืœืงืช ื”ืืคืœื™ืงืฆื™ื”:

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(). ื–ื” ื”ื›ืจื—ื™ ืขื‘ื•ืจ ืžื›ืฉื™ืจื™ ืื ื“ืจื•ืื™ื“ ืฉื›ืŸ ื™ืฉ ืœื”ืฆื™ื’ ืืช ื”ืจื›ื™ื‘ ื›ื“ื™ ืฉื”ืฉื™ื ื•ื™ื™ื ื™ื”ื™ื• ืžื•ืจื’ืฉื™ื.

ืœืื—ืจ ืžื›ืŸ ืขืœื™ืš ืœื”ืกื™ืจ ืืช ื”ื”ืื–ื ื” ืžื”ืฉื™ื˜ื” componentWillUnmount()โ€Ž.

ืœื‘ืกื•ืฃ, render() ืžื—ื–ื™ืจ hello ื‘ืืžืฆืขื•ืช translate() ื•ื”ื•ืกืคืช ืคืจืžื˜ืจ ืžืคืชื— ืืœื™ื•. ืœืื—ืจ ื”ืฉืœื‘ื™ื ื”ืœืœื•, ื”ืืคืœื™ืงืฆื™ื” ืชื•ื›ืœ "ืœื”ื‘ื™ืŸ" ืื™ื–ื• ืฉืคื” ื ื“ืจืฉืช ื•ืœื”ืฆื™ื’ ื‘ื” ื”ื•ื“ืขื•ืช.

ื”ืฉืงืช ื™ื™ืฉื•ืžื™ื

ืขื›ืฉื™ื• ื–ื” ื”ื–ืžืŸ ืœื‘ื“ื•ืง ืื™ืš ื”ืชืจื’ื•ื ืขื•ื‘ื“.

ืจืืฉื™ืช, ืื ื• ืžืคืขื™ืœื™ื ืืช ื”ืืคืœื™ืงืฆื™ื” ื‘ืกื™ืžื•ืœื˜ื•ืจ ืื• ื‘ืืžื•ืœื˜ื•ืจ ืขืœ ื™ื“ื™ ื”ืงืœื“ื”

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

ื–ื” ื™ื™ืจืื” ื‘ืขืจืš ื›ืš:

ื›ืชื™ื‘ืช ืืคืœื™ืงืฆื™ื” ืจื‘ ืœืฉื•ื ื™ืช ื‘-React Native

ื›ืขืช ืชื•ื›ืœ ืœื ืกื•ืช ืœืฉื ื•ืช ืืช ื”ืฉืคื” ืœืฆืจืคืชื™ืช ืขืœ ื™ื“ื™ ื”ืคืขืœืช ื”ืืคืœื™ืงืฆื™ื”.

ื›ืชื™ื‘ืช ืืคืœื™ืงืฆื™ื” ืจื‘ ืœืฉื•ื ื™ืช ื‘-React Native

ืื ื—ื ื• ืขื•ืฉื™ื ืืช ืื•ืชื• ื”ื“ื‘ืจ ืขื ืขืจื‘ื™ืช, ืื™ืŸ ื”ื‘ื“ืœ.

ื‘ื™ื ืชื™ื™ื ื”ื›ืœ ื˜ื•ื‘.

ืื‘ืœ ืžื” ืงื•ืจื” ืื ืชื‘ื—ืจ ื‘ืฉืคื” ืืงืจืื™ืช ืฉืื™ืŸ ืœื” ืชืจื’ื•ื ื‘ืืคืœื™ืงืฆื™ื”?

ืžืกืชื‘ืจ ืฉื”ืžืฉื™ืžื” ืฉืœ findBestLanguage ื”ื™ื ืœืกืคืง ืืช ื”ืชืจื’ื•ื ื”ืื•ืคื˜ื™ืžืœื™ ืžื›ืœ ื”ืชืจื’ื•ื ื”ื–ืžื™ื ื™ื. ื›ืชื•ืฆืื” ืžื›ืš, ืชื•ืฆื’ ืฉืคืช ื‘ืจื™ืจืช ื”ืžื—ื“ืœ.

ืื ื—ื ื• ืžื“ื‘ืจื™ื ืขืœ ื”ื’ื“ืจื•ืช ื”ื˜ืœืคื•ืŸ. ืœื“ื•ื’ืžื”, ื‘ืืžื•ืœื˜ื•ืจ iOS ื ื™ืชืŸ ืœืจืื•ืช ืืช ืกื“ืจ ื”ืฉืคื•ืช.

ื›ืชื™ื‘ืช ืืคืœื™ืงืฆื™ื” ืจื‘ ืœืฉื•ื ื™ืช ื‘-React Native

ืื ื”ืฉืคื” ืฉื ื‘ื—ืจื” ืื™ื ื” ื”ืฉืคื” ื”ืžื•ืขื“ืคืช, findBestAvailableLanguage ืžื—ื–ื™ืจื” ืœื ืžื•ื’ื“ืจืช ื›ืš ืฉืฉืคืช ื‘ืจื™ืจืช ื”ืžื—ื“ืœ ืชื•ืฆื’.

ื‘ื•ื ื•ืก

ืœ-react-native-localize ื™ืฉ API ื”ืžืกืคืง ื’ื™ืฉื” ืœืžืกืคืจ ืจื‘ ืฉืœ ืจื›ื™ื‘ื™ ืฉืคื”. ืœืคื ื™ ืฉืชืชื—ื™ืœ ืœืขื‘ื•ื“, ืฉื•ื•ื” ืœื‘ื“ื•ืง ืืช ื”ืชื™ืขื•ื“.

ืžืžืฆืื™ื

ื ื™ืชืŸ ืœื”ืคื•ืš ืืช ื”ืืคืœื™ืงืฆื™ื” ืœืจื‘ ืœืฉื•ื ื™ืช ืœืœื ื‘ืขื™ื•ืช. React-native-localize ื”ื™ื ืืคืฉืจื•ืช ืžืฆื•ื™ื ืช ื”ืžืืคืฉืจืช ืœืš ืœื”ืจื—ื™ื‘ ืืช ื‘ืกื™ืก ื”ืžืฉืชืžืฉื™ื ืฉืœ ื”ืืคืœื™ืงืฆื™ื” ืฉืœืš.

ืงื•ื“ ื”ืžืงื•ืจ ืฉืœ ื”ืคืจื•ื™ืงื˜ ืžืžื•ืงื ื›ืืŸ.

Skillbox ืžืžืœื™ืฆื”:

ืžืงื•ืจ: www.habr.com

ื”ื•ืกืคืช ืชื’ื•ื‘ื”