0
votes

I'm implementing i18n with reacti18next, on my react-native project, the i18n instance looks as following:

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;

And then I import the file on my index.js, from there im using the useTranslation hook on my components in order to translate some text, example:

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

Until here everything is working perfectly, now I was trying to figure out a way of letting every styled-component know the text direction(RTL/LTR), in order to update the flex-layout if I'm using a language that is RTL. Only idea I came up with was something like:

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;

This will work but will force me to call i18n.dir() in almost every component I have and pass it down to the smaller components.

Hoping someone can share some workaround for this situation, thanks

1

1 Answers

0
votes

You can maintain global state with contextApi and can access it on any page without having to call this const IsRTL = i18n.dir() === 'rtl'; on every page