Skip to main content

Header buttons

Now that we know how to customize the look and feel of our headers, let's make them smart! In fact, it might be ambitious, let's just give them the ability to react very clearly to our touch.

Adding a button to the title

The most common way to interact with a heading is to click the button to the left or right of the heading. Let's add a button to the right side of the header (one of the hardest places to tap on the entire screen, depending on your finger and phone size, but also a normal place to place buttons).

const screenOptions = {
headerTitle: props => <LogoTitle />,
headerRight: () => (
<Button
onPress={() => console.log('This is a button!')}
title="Info"
color="#fff"
/>
),
};

const StackScreen = () => {
return (
<Stack.Navigator>
<Stack.Screen
name="Home"
component={HomeScreen}
options={screenOptions}
/>
</Stack.Navigator>
);
}

Try this example on Snack

When we define our button in this way, the this variable in the options parameters is not an instance of HomeScreen, so you cannot call setState or any instance methods on it. This is very important because very often you want the buttons in your header to interact with the screen that the header belongs to. So, we'll see how to do this next.

How a title interacts with its display component

To be able to interact with the screen component, we need to use navigation.setOptions to define our button instead of the options property. By using navigation.setOptions inside a screen component, we can access screen properties, state, context, etc.

const StackScreen = () => {
return (
<Stack.Navigator>
<Stack.Screen
name="Home"
component={HomeScreen}
options={({ navigation, route }) => ({
headerTitle: props => <LogoTitle />
})}
/>
</Stack.Navigator>
)
}

const HomeScreen = ({ navigation }) => {
const [count, setCount] = React.useState(0)

React.useLayoutEffect(() => {
navigation.setOptions({
headerRight: () => (
<Button onPress={() => setCount(c => c + 1)} title="Update count" />
),
})
}, [navigation])

return <Text>Count: {count}</Text>
}

Back Button Setting

createStackNavigator provides platform-specific default settings for the back button. On iOS, this includes a label with a button that shows the title of the previous screen when the title fits into the available space, otherwise it says Back.

You can change the behavior of the label using headerBackTitle and headerTruncatedBackTitle more.

To customize the back button image, you can use headerBackImage.

Overriding the back button

The back button will automatically appear in the stack navigator whenever the user has the option to return from the current screen - in other words, the back button will appear whenever there is more than one screen in the stack.

All in all, this is what you need. But it is possible that in some circumstances you may want to customize the back button more than you can with the options mentioned above, in which case you can set the headerLeft option on the React element to be rendered, just like we do this was done with headerRight. Alternatively, the headerLeft option also accepts a React component that can be used, for example, to override the onPress behavior of the back button. Read more about this in API reference.

If you want to keep the look of the back button and only override the onPress method, you can import the HeaderBackButton from @response-navigation/stack

import { HeaderBackButton } from '@react-navigation/stack'

and assign this component to the headerLeft parameter.

Done

To see how well you learned this lesson, take the test in our school's mobile app on this topic or in Telegram bot.

EnglishMoji!

React Navigation

Contributors ✨

Thanks goes to these wonderful people (emoji key):


Dmitriy Vasilev

💲

EnglishMoji!