Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to set header title with value from redux state #313

Closed
mikeaxle opened this issue Feb 13, 2017 · 11 comments
Closed

How to set header title with value from redux state #313

mikeaxle opened this issue Feb 13, 2017 · 11 comments

Comments

@mikeaxle
Copy link

Hi, i connected react-navigation to redux and when I try to add values from redux as part of the header title, I get an error. What is the correct code to accomplish this?

my code:

    //define navigation option - show header
    static navigationOptions = {

        title: `Total: K${this.props.totalCharge}`,
        header: {
            visible: true,
        }
    };

the error:
screenshot_1486948710

@rmevans9
Copy link

rmevans9 commented Feb 13, 2017

AFAIK you can't hook directly to a redux store but you could do something like this:

class SuperManComponent extends React.Component {
    {...}
    static navigationOptions = {
        title: ({ state }) => `Total K:${state.params && state.params.totalCharge ? state.params.totalCharge : ''}`,
        {...}
    }
    {...}
    componentWillReceiveProps(nextProps) {
        if (nextProps.totalCharge) {
            this.props.navigation.setParams({ totalCharge });
        }
    }
}

const connectedSuperMan = connect(state => ({ totalCharge: state.ReducerYo.totalCharge }))(SuperManComponent);

This assumes total charge gets set in redux after you initial mount of the component. If it starts off populated you would do the setParams in the will mount or constructor as well since componentWillReceiveProps doesn't happen during initial mount of the component.

@ericvicenti
Copy link
Contributor

@rmevans9 is right, that is one way to do it, the other way is to have a pre-connected title component:

const MyTitle = ({ navigation, text }) => <TitleView text={text} navigation={navigation} />;
const MyConnectedTitle = connect(storeState => ({ text: storeState.title }))(MyTitle);

class SuperManComponent extends React.Component {
    {...}
    static navigationOptions = {
        title: (navigation) => <MyConnectedTitle navigation={navigation} />

@mikeaxle
Copy link
Author

@rmevans9 thanks, my problem was solved

@jordanmkoncz
Copy link

@rmevans9 Your solution worked for me too, cheers!

@yingdongzhang
Copy link

yingdongzhang commented Mar 15, 2018

@rmevans9

I did the same however I ran into two issues:
The first error was title cannot be written as a function like that so I had to use the full navigation.state.params
The second issue was componentWillReceiveProps gets called infinitely, which I didn't really figure out why, for some reason it triggers another componentWillReceiveProps call. Any ideas? Thanks

@cmendes0101
Copy link

cmendes0101 commented Mar 28, 2018

@yingdongzhang

Check to make sure only when the nextProp is changing

componentWillReceiveProps(nextProps) {
    if (this.totalCharge !== nextProps.totalCharge
        && nextProps.totalCharge) {
        this.props.navigation.setParams({ totalCharge });
    }
}

@yingdongzhang
Copy link

@cmendes0101

Thank you that makes sense. Cheers

@chawax
Copy link

chawax commented May 19, 2018

The componentWillReceiveProps method is deprecated from React 16.3, so this is no more the good place to set the header title. Any idea where we could do that ?

@KianooshSoleimani
Copy link

KianooshSoleimani commented Jun 27, 2018

its really simple you can make stateless component and connect it with redux like this :

  const view = ({ state, color }) => 
  {
  <View>
   <Text>{state.something}</Text>
  </View>
  }

export default connect(
    (state) => ({
       data: state.data,
    }),
    null
  )(view);

and then use it in static options :

static navigationOptions = ({ navigation }) => {
    return {
        tabBarIcon: ({ tintColor }) => <view color={tintColor}/>
    }
};

@EricWiener
Copy link

Please see this answer for an easier way to do this: https://stackoverflow.com/a/51883306/6942666

@The1nternet
Copy link

@rmevans9 is right, that is one way to do it, the other way is to have a pre-connected title component:

const MyTitle = ({ navigation, text }) => <TitleView text={text} navigation={navigation} />;
const MyConnectedTitle = connect(storeState => ({ text: storeState.title }))(MyTitle);

class SuperManComponent extends React.Component {
    {...}
    static navigationOptions = {
        title: (navigation) => <MyConnectedTitle navigation={navigation} />

When i try to use a connected component in navigationOptions.header, i get: TypeError: Object is not a function (near '...renderHeader...') . How can i add a connect() component to navigationOptions.header?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants