Bluefire
Bluefire

Reputation: 23

React Navigation - Dynamic Text (translations) needed in drawerNavigator drawerLabels from Redux store

Using react-navigation in a React Native app with Redux, I need to show drawerLabels in the drawerNavigation dynamically as they change depending on language. I therefore need to access the store and props (eg this.props.locale) but can't seem to get it working. Any help appreciated.

I've tried passing screenProps from the main parent appNavigator, which does have access to the store but not sure how to access them inside the drawerNavigator.

I don't really want to store the whole navigation in Redux as the docs imply this will not be supported in the future and can be avoided.

My root is AppNavigator, my settingsNavigation file is as follows.

    const BookingsNavigator = createStackNavigator (
    ...
    );

    ...

    const SettingsNavigator = createDrawerNavigator(
        {
            CurrentBookings: {
                screen: BookingsNavigator,
                navigationOptions: {
                    drawerLabel: 'My bookings',
                }
           },
       ...

       },

    );

const AppNavigator = createSwitchNavigator({  
    Bookings: BookingsNavigator,
   // other navigators
});

export default AppNavigator;

Upvotes: 2

Views: 1821

Answers (1)

Dmitry Preeternal
Dmitry Preeternal

Reputation: 378

For dynamic language change (in settings screen):

static navigationOptions = ({ navigation }) => {
    const { params } = navigation.state;
    return {
      title: i18n.t('settings.settings'), // drawer label initialization
      drawerLabel: params && params.DLabel,
      drawerIcon: ({ tintColor }) => (
        <Icon name="md-settings" style={{ fontSize: 24, color: tintColor }} />
      ),
    };
  };

  // no need to preset drawer label because we define title in navigationOptions
  // componentWillMount() {
  //   this.props.navigation.setParams({ DLabel: i18n.t('settings.settings') });
  // }

  componentDidUpdate(prevProps) {
    if (prevProps.language !== this.props.language) { // redux props from language picker
      // for current screen (drawer item)
      this.props.navigation.setParams({ DLabel: i18n.t('settings.settings') });
      // home screen (drawer item)
      const setHomeLabel = NavigationActions.setParams({
        params: { DLabel: I18n.t('home') },
        key: 'Home',
      });     
      this.props.navigation.dispatch(setHomeLabel);
      // inbox screen (drawer item)
      const setInboxLabel = NavigationActions.setParams({
        params: { DLabel: i18n.t('Inbox') },
        key: 'Inbox',
      });
      this.props.navigation.dispatch(setInboxLabel);
    }
  }

How to change the language:

  onLanguageChange = (value) => {
    this.props.languageChanged(value); // redux action from language picker
    i18n.locale = value === 0 ? 'ru' : 'en'; // set locale manually
  };

In home screen component:

static navigationOptions = ({ navigation }) => {
    const { params } = navigation.state;
    return {
      title: i18n.t('home'), // drawer label initialization
      drawerLabel: params && params.DLabel,
      drawerIcon: ({ tintColor }) => (
        <Icon
          type="Entypo"
          name="wallet"
          style={{ fontSize: 24, color: tintColor }}
        />
      ),
    };
  };

Upvotes: 2

Related Questions