Введение
Я всегда устанавливаю i18n (интернационализацию) в своих приложениях, даже если, вероятно, будет использоваться только один язык. Боль от адаптации приложения, которое изначально не считалось многоязычным, слишком велика, чтобы откладывать ее. К счастью, теперь у меня есть простая настройка с автодополнением с помощью машинописного текста, автоматическим определением языка пользователя и многим другим.
Настраивать
Чтобы получить пользовательский язык и обрабатывать наши переводы, мы используем 2 библиотеки:
React-native-localization: набор инструментов с простым API для получения локали, единиц измерения и часового пояса пользователя. (примечание: если вы используете expo, expo-localization также является хорошей библиотекой для использования)
react-i18next: мощный и популярный фреймворк для интернационализации в React/React-native.
npm install react-native-localize react-18next i18next
После установки нам нужен только один файл конфигурации и файлы JSON, которые будут содержать наши переводы для каждого языка.
import AsyncStorage from '@react-native-async-storage/async-storage' import i18n, { LanguageDetectorAsyncModule } from 'i18next' import { initReactI18next } from 'react-i18next' import * as RNLocalize from 'react-native-localize' import fr from './dictionaries/fr.json' export const locales = { fr: { translation: fr, }, } export const DEFAULT_LOCALE = 'fr' export const defaultLanguage = RNLocalize.findBestAvailableLanguage(Object.keys(locales))?.languageTag || DEFAULT_LOCALE export const currentLanguage = i18n.language || defaultLanguage const useLanguageStorage: LanguageDetectorAsyncModule = { type: 'languageDetector', async: true, detect: async (callback) => { AsyncStorage.getItem('language').then((lang) => { if (lang) return callback(lang) }) }, init: () => null, cacheUserLanguage: async (language: string) => { AsyncStorage.setItem('language', language) }, } i18n .use(useLanguageStorage) .use(initReactI18next) .init({ fallbackLng: defaultLanguage, resources: locales, react: { useSuspense: false, }, }) export default i18n
Затем вам нужно будет импортировать этот файл в свой App.tsx
и все.
Автозаполнение с помощью машинописного текста
Одна раздражающая вещь при использовании ключей перевода — это ввод путей снова и снова. Чтобы улучшить опыт разработчиков, я добавляю небольшое определение, чтобы получить предложения с помощью Typescript, это помогает избежать ошибок и сократить время кодирования.
Создайте файл react-18next.d.ts в корне каталога вашего проекта или в папке types
и добавьте этот код:
import 'react-i18next' import fr from './i18n/dictionaries/fr.json' declare module 'react-i18next' { // and extend them! interface Resources { translation: typeof fr } }
С этой настройкой у вас должно получиться что-то подобное в VScode
Применение
Наиболее распространенное использование
Почти каждый раз, когда текст используется на экране, вы добавляете этот текст, связанный с ключом в файле JSON, используете хук, предоставленный i18next
, который называется useTranslation
, и используете ключ в своем тексте.
Доступ вне компонентов
Иногда вам может понадобиться использовать ваши переводы вне ваших компонентов в файлах конфигурации или что-то еще. Для этого вы можете напрямую импортировать файл i18n и получить доступ к методу t
.
import i18next from './i18n' i18next.t('my.key')
Вложенные тексты/несколько стилей
Одной из мощных функций react-i18next является компонент Trans
, который может интерпретировать пользовательские теги в ваших переводах, чтобы использовать компонент для части вашего текста.
"myKey":"it is my text <color>colored part</color> end of text" <Text> <Trans components={{ color: <Text font="bold" color="primary" /> }} > {t("path.to.my.key"} </Trans> <Text>
Обновите язык
Для обновления языка вы используете тот же хук
const { t, i18n } = useTranslation(''); ... <Button onPress={()=>i18n.changeLanguage("de")>{i18n("switchLanguage")}</Button>Handle dates, currencies, API values
Обрабатывать даты, валюты, значения API
Для обработки дат я использую библиотеку dayjs, потому что это очень популярная библиотека, полная и имеет тот же API, что и Momentjs (которую я использовал в свое время).
import 'dayjs/locale/fr' // load on demand dayjs.locale('fr') // use French locale globally dayjs('2018-05-05').locale('fr-FR').format() // use on a specific textja
Для валют у вас есть несколько способов решить эту проблему, теперь я использую Intl.
const { i18n } = useTranslation() <Text>{Intl.NumberFormat(i18n.language, { style: 'currency', currency: 'EUR'}).format(45012)}</Text>
В заключение убедитесь, что все ваши формы/динамические значения связаны с слагом или ключом, связанным с вашим API. С такой настройкой добавить еще один язык будет очень быстро, а не утомительной задачей.
😄 Спасибо за прочтение! Если вы нашли эту статью полезной, подписывайтесь на меня в Твиттере, я делюсь советами по разработке, дизайну и делюсь своим путешествием по созданию собственной стартап-студии.
Первоначально опубликовано на antoinemesnil.com