How to integrate i18n-js in React Native Expo app

Viewed 6095

I'm having issues instantiating I18n in my Expo app. The TL;DR of the problem is that components that need the translations are rendered before

Expo.Util.getLocaleAsync()

returns and sets the locale. I can't figure out how to best set it up. As of now, I have a file for my instance of I18n, which I then import and use everywhere else in my app. It looks something like this:

import Expo from 'expo';
import I18n from 'i18n-js';
import english from './resources/strings/en';
import danish from './resources/strings/da';

I18n.defaultLocale = 'en-GB';
I18n.fallbacks = true;

I18n.initAsync = async () => {
  var locale = 'en-GB';
  try {
    locale = await Expo.Util.getCurrentLocaleAsync();
  } catch (error) {
    console.log('Error getting locale: ' + error);
  }

  I18n.locale = locale ? locale.replace(/_/, '-') : '';
};

I18n.translations = {
  en: english,
  da: danish,
};

export default I18n;

Then, in my root app component, I do the following:

import I18n from './src/i18n';

class App extends React.Component {
  async componentWillMount() {
    console.log('Current locale (main1): ' + I18n.currentLocale());
    try {
      await I18n.initAsync();
    } catch (error) {
      console.log('Error setting locale ' + error);
    }

    console.log('Current locale (main2): ' + I18n.currentLocale());
  }

  render() {
    return <AppContainer />;
  }
}

Expo.registerRootComponent(App);

The logs state the expected values - first the default locale, and then the updated locale in main2. The problem is that the child views are rendered with the first locale before the change is made, and I don't understand why?

I can't figure out a better way to do this, any ideas/tips would be much appreciated :-)

3 Answers

in react native expo it's easy.

1- step 1 install and import

expo install expo-localization

app.js

import { I18nManager } from 'react-native';
    import * as Localization from 'expo-localization';
    import i18n from 'i18n-js';

1- step 2 create an object with supported language.

i18n.translations = {
  en: { addPrice: 'add Price Here',subTax:' Sub Tax -'},
 ar: {addPrice: 'ادخل السعر هنا' ,subTax:'قبل ضريبة - '}
};

// Set the locale once at the starting app.

i18n.locale = Localization.locale;

// When a value is missing from a language it'll fallback to another language with the key present.

i18n.fallbacks = true;

//don't change app dir to rtl. 
I18nManager.forceRTL(false);
I18nManager.allowRTL(false);

1- step 3 use it Everywhere

<TouchableOpacity >

<Text >{i18n.t('subTax')}</Text>

</TouchableOpacity>
Related