将React i18next与样式化组件一起使用

时间:2019-10-31 12:06:53

标签: react-native styled-components i18next react-i18next

我正在用reacti18next实现i18n,在我的react-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;

然后,我使用组件上的useTranslation钩子从那里导入index.js文件,以翻译一些文本,例如:

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

直到这里一切都运行良好,现在我试图找出一种让每个样式化组件知道文本方向(RTL / LTR)的方式,以便在使用某种语言时更新弹性布局那就是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 :(得分:0)

您可以使用contextApi维护全局状态,并且可以在任何页面上访问它而不必调用此状态 const IsRTL = i18n.dir() === 'rtl'; 在每个页面上