
์๋ก์ด ๊ตญ๊ฐ์ ์ง์ญ์ ๊ฐ์ฒํ๋ ๊ตญ์ ๊ธฐ์
์๊ฒ ์ ํ ํ์งํ๋ ๋งค์ฐ ์ค์ํฉ๋๋ค. ๋ง์ฐฌ๊ฐ์ง๋ก ๋ชจ๋ฐ์ผ ์ ํ๋ฆฌ์ผ์ด์
์๋ ํ์งํ๊ฐ ํ์ํฉ๋๋ค. ๊ฐ๋ฐ์๊ฐ ํด์ธ ํ์ฅ์ ์์ํ๋ ๊ฒฝ์ฐ ๋ค๋ฅธ ๊ตญ๊ฐ์ ์ฌ์ฉ์์๊ฒ ๋ชจ๊ตญ์ด๋ก ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉํ ์ ์๋ ๊ธฐํ๋ฅผ ์ ๊ณตํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค. ์ด ๊ธฐ์ฌ์์๋ ํจํค์ง๋ฅผ ์ฌ์ฉํ์ฌ React Native ์ ํ๋ฆฌ์ผ์ด์
์ ์์ฑํฉ๋๋ค. .
Skillbox๋ ๋ค์์ ๊ถ์ฅํฉ๋๋ค. ๊ต์ก์ฉ ์จ๋ผ์ธ ๊ณผ์ .
์๋ฆผ: "Habr"์ ๋ชจ๋ ๋ ์๋ฅผ ์ํ - "Habr" ํ๋ก๋ชจ์ ์ฝ๋๋ฅผ ์ฌ์ฉํ์ฌ Skillbox ๊ณผ์ ์ ๋ฑ๋กํ ๋ 10 ๋ฃจ๋ธ ํ ์ธ.
๋๊ตฌ ๋ฐ ๊ธฐ์
์ด ๊ธ์ ์ดํดํ๋ ค๋ฉด React Native ์์ ์ ๋ํ ๊ธฐ๋ณธ ๊ธฐ์ ์ด ํ์ํฉ๋๋ค. ์์ ๊ธฐ๊ณ์ ์ค์ ์ ์ต์ํด์ง๋ ค๋ฉด ๋ค์์ ์ํํ์ญ์์ค. .
๋ค์ ๋ฒ์ ์ ์ํํธ์จ์ด ๋๊ตฌ๊ฐ ํ์ํฉ๋๋ค.
- ๋ ธ๋ v10.15.0
- npm 6.4.1
- ํธ์ค 1.16.0
- ๋ฐ์ ๋ค์ดํฐ๋ธ 0.59.9
- ๋ฐ์ ๋ค์ดํฐ๋ธ ํ์งํ 1.1.3
- i18n-js 3.3.0
ะะฐัะธะฝะฐะตะผ
์์ด, ํ๋์ค์ด, ์๋์ด๋ฅผ ์ง์ํ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ง๋ค๊ฒ ์ต๋๋ค. ๋จผ์ React-native-cli๋ฅผ ์ฌ์ฉํ์ฌ ์ ํ๋ก์ ํธ๋ฅผ ์์ฑํฉ๋๋ค. ์ด๋ ๊ฒ ํ๋ ค๋ฉด ํฐ๋ฏธ๋์ ๋ค์์ ์ ๋ ฅํด์ผ ํฉ๋๋ค.
$ ๋ฐ์ ๋ค์ดํฐ๋ธ ์ด๊ธฐํ ๋ค๊ตญ์ด
$ cd ๋ค๊ตญ์ด
ํ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ถ๊ฐ
์ฒซ ๋ฒ์งธ ๋จ๊ณ๋ ๋ค์์ ์
๋ ฅํ์ฌ React-native-localize๋ฅผ ์ค์นํ๋ ๊ฒ์
๋๋ค.
$ ์์ฌ ๋ฐ์ ๋ค์ดํฐ๋ธ ํ์งํ ์ถ๊ฐ
์ค์น ๊ณผ์ ์์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ๊ฒฝ์ฐ, .
React-native-localize ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ๊ฐ๋ฐ์์๊ฒ ๋ค๊ตญ์ด ๊ธฐ๋ฅ์ ๋ํ ์ก์ธ์ค๋ฅผ ์ ๊ณตํฉ๋๋ค. ํ์ง๋ง ๊ทธ๋ ์๊ฒ๋ i18n์ด๋ผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ํ๋ ๋ ํ์ํฉ๋๋ค.
์ด ๋ฌธ์์์๋ ์ฌ์ฉ๋ฒ์ ์ค๋ช ํฉ๋๋ค. JavaScript๋ก ๋ฒ์ญ์ ์ ๊ณตํ๊ธฐ ์ํด.
$ ์์ฌ i18n-js ์ถ๊ฐ
i18n-js๋ ์บ์ฑ์ด๋ ๋ฉ๋ชจ ๊ธฐ๋ฅ์ ์ ๊ณตํ์ง ์์ผ๋ฏ๋ก ์ด๋ฅผ ์ํด lodash.memoize๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
$ ์์ฌ lodash.memoize ์ถ๊ฐ
๋ฒ์ญ ์์
์ ํ๋ฆฌ์ผ์ด์ ์ด ๋ค๋ฅธ ์ธ์ด์ ์๋ํ ์ ์์ผ๋ ค๋ฉด ๋จผ์ src ๋ด์ ๋ฒ์ญ ๋๋ ํฐ๋ฆฌ๋ฅผ ๋ง๋ ๋ค์ ๊ฐ ์ธ์ด์ ๋ํ ์ธ ๊ฐ์ JSON ํ์ผ์ ๋ง๋ค์ด์ผ ํฉ๋๋ค.
1. ์์ด์ ๊ฒฝ์ฐ en.json;
2. ํ๋์ค์ด์ ๊ฒฝ์ฐ fr.json;
3. ์๋์ด์ ๊ฒฝ์ฐ ar.json.
์ด๋ฌํ ํ์ผ์๋ ํค์ ๊ฐ์ด ํฌํจ๋ JSON ๊ฐ์ฒด๊ฐ ํฌํจ๋์ด ์์ต๋๋ค. ํค๋ ๊ฐ ์ธ์ด๋ง๋ค ๋์ผํฉ๋๋ค. ์ด๋ ์์ฉ ํ๋ก๊ทธ๋จ์์ ํ ์คํธ ์ ๋ณด๋ฅผ ํ์ํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
๊ฐ์ ์ฌ์ฉ์์๊ฒ ํ์๋์ด์ผ ํ๋ ํ ์คํธ์ ๋๋ค.
์์ด:
{"์๋ ํ์ธ์": "์๋ ํ์ธ์!"}
ะคัะฐะฝััะทัะบะธะน
{"์๋ ํ์ธ์": "Salut le Monde!"}
ะัะฐะฑัะบะธะน
{ "์๋ ํ์ธ์": "ุงููุงู ุจุงูุนุงูู "}
๊ฐ์ ๋ฐฉ๋ฒ์ผ๋ก ๋ค๋ฅธ ์ธ์ด๋ ์ถ๊ฐํ ์ ์์ต๋๋ค.
๋ฉ์ธ์ฝ๋
์ด ์์ ์์ 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()์ ์ด๋ฒคํธ ๋ฆฌ์ค๋๋ฅผ ์ถ๊ฐํด์ผ ํฉ๋๋ค. ์ด ์์๋ ์ ๋ฐ์ดํธ๋ฅผ ์์ ํ๊ณ ์ ๋ฐ์ดํธ๊ฐ ๋ฐ์ํ๋ฉด handlerLocalizationChange()๋ฅผ ํธ์ถํฉ๋๋ค.
ะะตัะพะด handleLocalizationChange() ะฐะบัะธะฒะธะทะธััะตั setI18nConfig() ะธ forceUpdate(). ะญัะพ ะฝะตะพะฑั ะพะดะธะผะพ ะดะปั ััััะพะนััะฒ ะฝะฐ Android, ัะฐะบ ะบะฐะบ ะบะพะผะฟะพะฝะตะฝั ะดะพะปะถะตะฝ ะฑััั ะพััะตะฝะดะตัะตะฝ, ััะพะฑั ะธะทะผะตะฝะตะฝะธั ััะฐะปะธ ะทะฐะผะตัะฝัะผะธ.
๊ทธ๋ฐ ๋ค์ componentWillUnmount() ๋ฉ์๋์์ ์ฒญ์ทจ๋ฅผ ์ ๊ฑฐํด์ผ ํฉ๋๋ค.
๋ง์ง๋ง์ผ๋ก render()๋ ๋ฒ์ญ()์ ์ฌ์ฉํ๊ณ ์ฌ๊ธฐ์ ์ฃผ์ ๋งค๊ฐ๋ณ์๋ฅผ ์ถ๊ฐํ์ฌ hello๋ฅผ ๋ฐํํฉ๋๋ค. ์ด ๋จ๊ณ๋ฅผ ๋ง์น๋ฉด ์ ํ๋ฆฌ์ผ์ด์ ์ ์ด๋ค ์ธ์ด๊ฐ ํ์ํ์ง "์ดํด"ํ๊ณ ๊ทธ ์์ ๋ฉ์์ง๋ฅผ ํ์ํ ์ ์์ต๋๋ค.
์ ํ๋ฆฌ์ผ์ด์ ์ถ์
์ด์ ๋ฒ์ญ์ด ์ด๋ป๊ฒ ์งํ๋๋์ง ํ์ธํ ์๊ฐ์ ๋๋ค.
๋จผ์ ์๋ฎฌ๋ ์ดํฐ๋ ์๋ฎฌ๋ ์ดํฐ์์ ๋ค์์ ์ ๋ ฅํ์ฌ ์ ํ๋ฆฌ์ผ์ด์ ์ ์์ํฉ๋๋ค.
$ ๋ฐ์ ๋ค์ดํฐ๋ธ ์คํ iOS
$ ๋ฐ์ ๋ค์ดํฐ๋ธ ์คํ ์๋๋ก์ด๋
๋ค์๊ณผ ๊ฐ์ด ๋ณด์ผ ๊ฒ์
๋๋ค:

์ด์ ์ ํ๋ฆฌ์ผ์ด์
์ ์คํํ์ฌ ์ธ์ด๋ฅผ ํ๋์ค์ด๋ก ๋ณ๊ฒฝํ ์ ์์ต๋๋ค.

์ฐ๋ฆฌ๋ ์๋์ด์๋ ๋๊ฐ์ ์ผ์ ํฉ๋๋ค. ์ฐจ์ด๋ ์์ต๋๋ค.
์ฌํ๊น์ง๋ ๊ทธ๋ฐ๋๋ก ์๋๋ค.
ํ์ง๋ง ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ฒ์ญ์ด ์๋ ์ธ์ด๋ฅผ ๋ฌด์์๋ก ์ ํํ๋ฉด ์ด๋ป๊ฒ ๋ ๊น์?
findBestLanguage์ ์๋ฌด๋ ์ฌ์ฉ ๊ฐ๋ฅํ ๋ชจ๋ ๋ฒ์ญ ์ค์์ ์ต์ ์ ๋ฒ์ญ์ ์ ๊ณตํ๋ ๊ฒ์ ๋๋ค. ๊ฒฐ๊ณผ์ ์ผ๋ก ๊ธฐ๋ณธ ์ธ์ด๊ฐ ํ์๋ฉ๋๋ค.
์ฐ๋ฆฌ๋ ์ ํ ์ค์ ์ ๋ํด ์ด์ผ๊ธฐํ๊ณ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด iOS ์๋ฎฌ๋ ์ดํฐ์์๋ ์ธ์ด ์์๋ฅผ ๋ณผ ์ ์์ต๋๋ค.

์ ํํ ์ธ์ด๊ฐ ๊ธฐ๋ณธ ์ธ์ด๊ฐ ์๋ ๊ฒฝ์ฐ findBestAvailableLanguage๋ ๊ธฐ๋ณธ ์ธ์ด๊ฐ ํ์๋๋๋ก ์ ์๋์ง ์์ ๊ฐ์ ๋ฐํํฉ๋๋ค.
๋ณด๋์ค
React-native-localize์๋ ์๋ง์ ์ธ์ด ์์์ ๋ํ ์ก์ธ์ค๋ฅผ ์ ๊ณตํ๋ API๊ฐ ์์ต๋๋ค. ์ผ์ ์์ํ๊ธฐ ์ , .
์กฐ์ฌ ๊ฒฐ๊ณผ
์์ฉ ํ๋ก๊ทธ๋จ์ ๋ฌธ์ ์์ด ๋ค๊ตญ์ด๋ก ๋ง๋ค ์ ์์ต๋๋ค. React-native-localize๋ ์ฑ์ ์ฌ์ฉ์ ๊ธฐ๋ฐ์ ํ์ฅํ ์ ์๋ ํ๋ฅญํ ์ต์ ์ ๋๋ค.
ํ๋ก์ ํธ ์์ค ์ฝ๋ .
Skillbox๋ ๋ค์์ ๊ถ์ฅํฉ๋๋ค.
- XNUMX๋ ์ค์ต ์ฝ์ค .
- ์จ๋ผ์ธ ์ฝ์ค .
- ์ค๊ธฐ ์ฝ์ค .
์ถ์ฒ : habr.com
