5

I need to read one value and use it to set title in navigation bar.
I am using react-native-router-flux and I also use redux.
I navigate to view where I set language and fire redux action.
All views receive new state and in render() method I can call:

console.log(this.props.language.language)

This is set through redux. And I want to change navigation bar title like:

Actions.refresh({title: I18n.t('main', {locale: this.props.language.language})})

But this slows down application and don't work.
But don't know where to put it if not in render method.

1110
  • 7,829
  • 55
  • 176
  • 334

5 Answers5

1

You can change navigation title by setting navigation params as follows:

this.props.navigation.setParams({
    title: 'YOUR_DESIRED_TITLE_HERE',
});
gypsicoder
  • 5,416
  • 5
  • 24
  • 38
0

You shouldn't be modifying state in your render methods - this will result in an infinite loop of changing state causing re-renders.

Instead you should put this in a lifecycle method:

componentDidMount () {
  Actions.refresh(...)
}

Which will be fired when the component is first mounted.

Tom Walters
  • 15,366
  • 7
  • 57
  • 74
  • But component is already mounted. It's first screen then I navigate to second and changed language. I son't know how to make update in first screen now. Is there some method like viewWillApper in ios, fired whenever screen is shown? – 1110 Feb 24 '17 at 14:50
  • 1
    The closest thing would be [`componentWillReceiveProps`](https://facebook.github.io/react/docs/react-component.html#componentwillreceiveprops) which is passed new props whenever they change. – Tom Walters Feb 24 '17 at 14:53
  • This method also doesn't help. It is not called when I open view it is called when I update state via redux. At that time that screen is not visible so again I can't update title. – 1110 Feb 24 '17 at 14:56
0

You could try storing the current language in a closure that is globally accessible throughout the application.

This will allow you to set the language state in the constructor of your components, which ensures that it will be present throughout the life cycle of the component.

// Settings.js
var Settings = (function() {
  var language = "EN"; // The default language

  var getLanguage = function() {
    return language;
  };
  var setLanguage = function(lang) {
    language = lang;
  };

  return {
    getLanguage: getLanguage,
    setLanguage: setLanguage
  }
})();

export default Settings;

When you want to get the current language, and set state in your component:

import Settings from './Settings';
... 
constructor(props) {
  super(props);
  this.state = {
    language: Settings.getLanguage()
  }
}

When you want to set or change the current language:

import Settings from './Settings';
... 
Settings.setLanguage('FR');

// Do something like reload here?
grizzthedj
  • 7,131
  • 16
  • 42
  • 62
0

If I clearly understand your question you should use React Lifecycle method componentWillReceiveProps()

componentWillReceiveProps(nextProps){
    let { language } = nextProps.language;
    if (language && language != this.props.language.language) {
      Actions.refresh({title: I18n.t('main', {locale: language})})
    }
}
Alex Shtromberg
  • 740
  • 8
  • 21
0

I guess what you're missing is the key of the component, where your keys are defined in Router > Scene tree.

Actions.refresh({key: 'somekey', title: I18n.t('main', {locale: this.props.language.language})})

However, it may just not about it, and from my experiences, I can help you with a sneaky hack. This is a workaround I discovered when Actions doesn't work even though component has already been mounted.

Just wrap your action with a timeout, and it works. This workaround originally inspired from the fact that firing two Action commands consecutively will omit the first one.

Place it in componentDidMount(){} or in componentWillReceiveProps(){} if you like Redux to trigger this function as well.

setTimeout(() => {
   Actions.refresh({key: 'somekey', title: I18n.t('main', {locale: this.props.language.language})}, 200); // give him some space!
});

Hope this is really the case.

eden
  • 5,876
  • 2
  • 28
  • 43