React-native : Dynamically update header title in stack navigator

Viewed 70853

I have made a custom component for header title(stack navigator)which shows user name along with some image. On this page I have to edit the username and on success Update it in header as well

So my question is How to change/update title dynamically?

12 Answers

For React Navigation version 1.x, 2.x, 3.x and 4.x, you can simply change the header by using the method shown in the code below, or the one in the original documentation: React Navigation - using params in the title

 static navigationOptions = ({ navigation }) => {
    const edit = navigation.getParam('edit', false);
    if(edit){
      return {
        headerTitle: 'Edit Page',
      };
    }else{
      return {
        headerTitle: 'Normal Page',
      };
    }
 };

For version 5.x and above, you may refer to the code below. Here are the links for the official documentation and example in expo.

import * as React from 'react';
import { View, Text, Button } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';

function HomeScreen({ navigation }) {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Home Screen</Text>
      <Button
        title="Go to Profile"
        onPress={() =>
          navigation.navigate('Profile', { name: 'Custom profile header' })
        }
      />
    </View>
  );
}

function ProfileScreen({ navigation }) {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Profile screen</Text>
      <Button title="Go back" onPress={() => navigation.goBack()} />
    </View>
  );
}

const Stack = createStackNavigator();

function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen
          name="Home"
          component={HomeScreen}
          options={{ title: 'My home' }}
        />
        <Stack.Screen
          name="Profile"
          component={ProfileScreen}
          options={({ route }) => ({ title: route.params.name })}
        />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

export default App;

In React 5.0 or above you could do the following if you want to use a Class Component:

 componentDidMount() {
   this.props.navigation.setOptions({
     title: `Your Updated Title`,
   })
 }

With React Navigation 5 and React Navigation 6 you can do this like this, set Params in your component

props.navigation.navigate("ProductDetailScreen", {
      productId: itemData.item.id,
      productTitle: itemData.item.title,
    });

And display it

<Stack.Screen
      name="ProductDetailScreen"
      component={ProductDetailScreen}
      options={({ route }) => ({ title: route.params.productTitle })} // what 
need to add
/>

or you can do this in your component with useEffect hooks

useEffect(() => {
    props.navigation.setOptions({
      title: productTitle,
    });
  }, [productTitle, props.navigation]);
 navigation.setOptions({ title: 'Updated!' })

Reference.

the code that shows in the part below is for the version of react-navigation 2.x

you can try the following:

in my case I have the configuration of navigation in a file called, app-navigator.js

const ChatStackNavigator = createStackNavigator(
    {
        People: ListPeopleScreen, // People Screen,
        Screen2: Screen2
    },
    {
        initialRouteName: 'People'
        navigationOptions: ({navigation}) => ({
            header: <AppBar title={navigation.getParam('appBar', {title: ''}).title}/>
        }),
        cardStyle: {
            backgroundColor: 'white'
        }
    }
);

The screen file would be as follows:

import React, {Component} from 'react';
import {connect} from 'react-redux';
import {List, ListItem} from 'react-native-elements';

class ListPeopleScreen extends Component {

    list = [
        {
            name: 'Amy Farha',
            avatar_url: 'https://s3.amazonaws.com/uifaces/faces/twitter/ladylexy/128.jpg',
            subtitle: 'Vice President'
        },
        {
            name: 'Chris Jackson',
            avatar_url: 'https://s3.amazonaws.com/uifaces/faces/twitter/adhamdannaway/128.jpg',
            subtitle: 'Vice Chairman'
        }
    ];

    componentDidMount() {
        this.props.navigation.setParams({
            appBar: {
                title: 'Clientes'
            }
        });
    }

    render() {
        return <List
            containerStyle={{marginBottom: 30}}
        >
            {
                this.list.map((item) => (
                    <ListItem
                        roundAvatar
                        avatar={{uri: item.avatar_url}}
                        key={item.name}
                        title={item.name}
                    />
                ))
            }
        </List>
    };
}

export default connect(null)(ListPeopleScreen);

NOTE: in my case I am using redux, and the library of components react-native-elements

In version 3.x and 4.x this can be done using static navigationOptions function,

For class compenents,

class MyComponent extends Component {
  static navigationOptions = ({navigation}) => {
    return {
      title: navigation.getParam('title', 'Fallback title');
    };
  }

  updateHeader = () => {
    // dynamically update header
    navigation.setParams({title: 'MyComponent'});
  }

  render() {
    // call updateHeader on click of any component
  }
}

For functional components,

const MyComponent = (props) => {
  const updateHeader = () => {
    // dynamically update header
    navigation.setParams({title: 'MyComponent'});
  }

  // call updateHeader on click of any component
}

MyComponent.navigationOptions = ({navigation}) => ({
  title: navigation.getParam('title', 'Fallback title'),
})

for react navigation Version: 5.x

   const ProductDetailScreen = props => {
       const { productId } = props.route.params;
       const { productTitle } = props.route.params;

       props.navigation.setOptions({ title: productTitle });

       return  (
            <View>
                <Text>{productId}</Text>
            </View>
        );
     };

for react navigation Version: 5.x

For version 4, this is work for me.

    const HistoryScreen: NavigationStackScreenComponent<any, any> = (props) => {
  const { navigation } = props;

  useEffect(() => {
    let device = props.navigation.getParam("device");
    if(device) {
        navigation.setParams({title: `History - ${device.name}`})
    }
  }, []);

    ... render view

    HistoryScreen.navigationOptions = ({
      navigationOptions,
      navigation,
    }) => ({
      headerTitle: navigation.getParam("title") ? navigation.getParam("title") : "History"
    });
}
function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen
          name="OrdersScreen"
          component={OrdersScreen}
          options={{ title: 'My Orders' }}
        />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

For React-Navigation v3, I used the following command to change the title of a stack:

Class component:

this.props.navigation.setParams({ title: res.title });

Function component:

props.navigation.setParams({ title: res.title });

If you use createStackNavigator you can do like this:

createStackNavigator({
  // For each screen that you can navigate to, create a new entry like this:
  Profile: {
    // `ProfileScreen` is a React component that will be the main content of the screen.
    screen: ProfileScreen,
    // When `ProfileScreen` is loaded by the StackNavigator, it will be given a `navigation` prop.

    // Optional: When deep linking or using react-navigation in a web app, this path is used:
    path: 'people/:name',
    // The action and route params are extracted from the path.

    // Optional: Override the `navigationOptions` for the screen
    navigationOptions: ({ navigation }) => ({
      title: `${navigation.state.params.name}'s Profile'`,
    }),
  },

  ...MyOtherRoutes,
});

from the doc

call it like this:

navigation.navigate('Profile', {_id: item._id, name: item.screenName})}
Related