Использование реакции i18next с styled-компонентами - PullRequest
0 голосов
/ 31 октября 2019

Я реализую i18n с activti18next, в моем проекте Reaction-native экземпляр i18n выглядит следующим образом:

import i18next from 'i18next';
import { initReactI18next } from 'react-i18next';
import * as RNLocalize from 'react-native-localize';
import AsyncStorage from '@react-native-community/async-storage';

import { languages } from 'Base/config.json';

const translations = {
  en: { translation: require('Assets/translations/en.json') },
  pt: { translation: require('Assets/translations/pt.json') },
};

const languageDetector = {
  type: 'languageDetector',
  async: true,
  detect: async (callback) => {
    const storedLanguageTag = await AsyncStorage.getItem('selectedLanguageTag');
    if (storedLanguageTag) {
      return callback(storedLanguageTag);
    }

    const { languageTag: deviceBestAvailableLanguage } = RNLocalize.findBestAvailableLanguage(
      languages.available,
    );

    callback(deviceBestAvailableLanguage || languages.default);
  },
  init: () => {},
  cacheUserLanguage: () => {},
};

const i18n = i18next.createInstance();

i18n
  .use(languageDetector)
  .use(initReactI18next)
  .init({
    fallbackLng: languages.default,
    resources: translations,
  });

export default i18n;

И затем я импортирую файл в мой index.js, откуда я используюхук useTranslation для моих компонентов, чтобы перевести некоторый текст, например:

<NavText>{t('menu.about')}</NavText>

Пока здесь все не работает идеально, теперь я пытался найти способ дать каждому стилевому компоненту знать направление текста(RTL / LTR), чтобы обновить flex-макет, если я использую язык RTL. Единственная идея, которую я придумал, была что-то вроде:

import React from 'react';
import { useTranslation } from 'react-i18next';

import { Picker } from 'Components/formElements';
import SettingsItemHeader from './settingsItemHeader';
import { SettingsItem, SettingsItemTittle } from './style';
import { languages } from 'Base/config.json';

const OtherSettings = () => {
  const { t, i18n } = useTranslation();
  const IsRTL = i18n.dir() === 'rtl';

  const a = languages.available.map((languageKey) => ({
    key: languageKey,
    label: t(`settings.languages.${languageKey}`),
  }));

  const onChangeLanguagePress = (option) => {
    i18n.changeLanguage(option.key);
  };

  return (
    <>
      <SettingsItemHeader name={t('settings.others')} IsRTL={IsRTL} />
      <SettingsItem isLastItem>
        <SettingsItemTittle>{t('settings.select_language')}</SettingsItemTittle>
        <Picker data={a} selectedKey={i18n.languages[0]} onChange={onChangeLanguagePress} />
      </SettingsItem>
    </>
  );
};

export default OtherSettings;

Это будет работать, но заставит меня вызывать i18n.dir () почти для каждого компонента, который у меня есть, и передавать его меньшим компонентам. *

Надеясь, что кто-то может поделиться некоторым обходным путем для этой ситуации, спасибо

1 Ответ

0 голосов
/ 31 октября 2019

Вы можете поддерживать глобальное состояние с contextApi и иметь доступ к нему на любой странице, не вызывая этот const IsRTL = i18n.dir() === 'rtl'; на каждой странице

...