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 :-)
This is what worked for me:
In main.js
:
import I18n from 'react-native-i18n';
class App extends React.Component {
state = {
appIsReady: false,
}
async componentWillMount() {
await I18n.initAsync();
this.setState({appIsReady: true});
}
render() {
if (!this.state.appIsReady) {
return (
<AppLoading />
);
}
return (
<RootComponent>
);
)
and in some component:
import I18n from '../i18n';
render() {
return (
<View>
<Text>{I18n.t('favorites')}</Text>
<Text>{I18n.locale}</Text>
</View>
)
}
And from the root dir I created i18n/index.js
:
import I18n from 'react-native-i18n';
I18n.fallbacks = true; // let 'en-GB' fallback to 'en' if not found
I18n.translations = {
'en': require('./en.json'),
'nl': require('./nl.json'),
}
export default I18n;
my initial Dutch translation file in i18n/nl.json
:
{
favorites: 'Jouw Favorieten',
}
I have this in my package.json
:
"react-native-i18n": "git+https://github.com/xcarpentier/ex-react-native-i18n.git",
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With