the i18n work in all my app (android &ios)
I use redux and AsyncStorage to store the choosen langage by user to don't ask it each time.
Today is see that i forget to translate my StackNavigator navigationOptions title.
but it don't work for me. the StackNavigator's titles stays in the default langage (french as my phone)
How to solve this please ?
import I18n from "react-native-i18n";
I18n.fallbacks = true;
I18n.translations = {
"en": require("./en.json"),
"en-EN": require("./en.json"),
"fr": require("./fr.json"),
"fr-FR": require("./fr.json"),
};
export default I18n;
import I18n from '../i18n/i18n';
class SettingPage extends Component {
static navigationOptions = {
title: I18n.t("SettingPage.Settings"), // it stay in french whatever choosen langage
tabBarLabel: I18n.t("SettingPage.Settings"),
tabBarIcon: ({ tintColor }) => <Icon name="cog" size={20} color="#fff" />
};
constructor(props) {
super(props); ...
}
render() {
return (
<View >
<Text>{I18n.t("SettingPage.Settings")}</Text> // it is translated on real time
....
</View>
);
}
// my apps.s is very big, i use a StackNavigator and a TabNavigator, so i remove some parts
import I18n from './i18n/i18n';
const MyTabView = TabNavigator(
{
NvObs: { screen: NouvelleObservation },
...
Options: { screen: Optionpage }
},
{ ... }
);
class MyGlobalComponent extends Component {
constructor(props) {
super(props);
}
goToCamera = () => { this.props.navigation.navigate("NvObs"); };
render() {
return (
<View style={{ flex: 1 }}>
<MyTabView
navigation={this.props.navigation}
screenProps={{ navigation: this.props.navigation }}
/>
<ActionButton > ... </ActionButton>
</View>
);
}
}
MyGlobalComponent.router = MyTabView.router;
const StackView = StackNavigator({
global: { screen: MyGlobalComponent},
NvObs: { screen: NouvelleObservation },
profile: { screen: ProfilePage }, // the title of this stacknavigator is not translated
setting: { screen: SettingPage }, // the title of this stacknavigator is not translated
dons: { screen: DonsPage }, // the title of this stacknavigator is not translated
othersoft: { screen: OthersoftPage }, // the title of this stacknavigator is not translated
login: { screen: LoginPage } // the title of this stacknavigator is not translated
});
import * as actions from "./redux/actions";
export default class App extends Component {
constructor(props) {
super(props);
this.state = { ...store.getState() };
I18n.locale = store.getState().language ;
this.unsubscribe = store.subscribe(() => {
const storestate = store.getState();
if(storestate.language!=null){
I18n.locale = storestate.language ;
}
});
}
render() {
return (
<Provider store={store}>
<View style={{ flex: 1 }}>
<StackView />
</View>
</Provider>
);
}
}
Because all the static properties are executed before your store subscription function is set the locale from the store. The navigationOptions have to be lazy to work.
Change all static navigationOptions to lazy functions.
Before:
static navigationOptions = {
title: I18n.t("SettingPage.Settings"), // it stay in french whatever choosen langage
tabBarLabel: I18n.t("SettingPage.Settings"),
tabBarIcon: ({ tintColor }) => <Icon name="cog" size={20} color="#fff" />
};
After:
static navigationOptions = () => ({
title: I18n.t("SettingPage.Settings"), // it stay in french whatever choosen langage
tabBarLabel: I18n.t("SettingPage.Settings"),
tabBarIcon: ({ tintColor }) => <Icon name="cog" size={20} color="#fff" />
});
With this change, all static navigationOptions are executed when the screen is entered.
Also, if you don't need the device language, you can just use i18n-js directly.
@patlux not working for me...
// header navigation options
static navigationOptions = () => ({
title: I18n.t('settings'),
headerStyle: {
backgroundColor: '#4285f4',
},
headerTitleStyle: {
color: 'white'
}
});
@patlux It's not working for me.
not working for me as well
Because all the static properties are executed before your store subscription function is set the locale from the store. The navigationOptions have to be lazy to work.
Change all static navigationOptions to lazy functions.
Before:
static navigationOptions = { title: I18n.t("SettingPage.Settings"), // it stay in french whatever choosen langage tabBarLabel: I18n.t("SettingPage.Settings"), tabBarIcon: ({ tintColor }) => <Icon name="cog" size={20} color="#fff" /> };After:
static navigationOptions = () => ({ title: I18n.t("SettingPage.Settings"), // it stay in french whatever choosen langage tabBarLabel: I18n.t("SettingPage.Settings"), tabBarIcon: ({ tintColor }) => <Icon name="cog" size={20} color="#fff" /> });With this change, all static navigationOptions are executed when the screen is entered.
You made my day Bro.. Excellent solution.
Solution above won't doesn't work in react-native for me. Ended up doing:
import React from "react";
import {Text} from "react-native";
import {useTranslation} from "react-i18next";
export const NavigationLabel = ({path}) => {
const {t} = useTranslation();
return <Text>{t(path)}</Text>;
};
static navigationOptions = () => ({
title: <NavigationLabel path="Home" />
});
Most helpful comment
Because all the static properties are executed before your store subscription function is set the locale from the store. The navigationOptions have to be lazy to work.
Change all static navigationOptions to lazy functions.
Before:
After:
With this change, all static navigationOptions are executed when the screen is entered.