React-native-i18n: error with navigationOptions title

Created on 17 Oct 2017  路  7Comments  路  Source: AlexanderZaytsev/react-native-i18n

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 ?

/i18n/i18n.js

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;

/settingPage.js

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>
    );
  }

/App.s :

 // 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>
    );
  }
}

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:

  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.

All 7 comments

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" />
});

https://stackoverflow.com/questions/53484087/react-native-react-i18next-react-navigation-navigationoptions-update-issue

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mekaVR picture mekaVR  路  5Comments

ansmonjol picture ansmonjol  路  6Comments

SvetoslavSlavov picture SvetoslavSlavov  路  4Comments

henrikra picture henrikra  路  4Comments

wyzzy picture wyzzy  路  5Comments