Настройка Header
We've already seen how to set the title
in the Header, but let's take another look at that before moving on to some of the other options - repetition is the key to learning!
Set up title
in Header
The Screen
component accepts an options
option, which is either an object or a function that returns an object containing various configuration options. We use title
as the title, as shown in the following example.
const StackScreen = () => {
return (
<Stack.Navigator>
<Stack.Screen
name="Home"
component={HomeScreen}
options={{ title: 'My home' }}
/>
</Stack.Navigator>
)
}
Using parameters in the header
To use the options in the header, we need to make the options
for the screen a function that returns a configuration object. It might be tempting to try using this.props
inside parameters, but since it is defined before the component is rendered, this does not apply to the component instance, and therefore properties are not available. Instead, if we make the parameters a function, then React Navigation will call it with an object containing {navigation, route}
- in this case all we care about is the route, which is the same object that is passed to the properties of your screen as a route property. You may recall that we can get parameters via route.params
, and so we do it below to extract the parameter and use it as a header.
import * as React from 'react'
import { View, Text, Button } from 'react-native'
import { NavigationContainer } from '@react-navigation/native'
import { createStackNavigator } from '@react-navigation/stack'
const HomeScreen = ({ navigation }) => (
<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>
)
const ProfileScreen = ({ navigation }) => (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Profile screen</Text>
<Button title="Go back" onPress={() => navigation.goBack()} />
</View>
)
const Stack = createStackNavigator()
const App = () => (
<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
The argument passed to the parameters function is an object with the following properties:
navigation
- prop for the screenroute
- prop route for the screen
In the example above, we only needed route support, but in some cases you can also use navigation.
Updating options with setOptions
It is often necessary to update the option configuration for the active display from the connected display component itself. We can do this with navigation.setOptions
/* Inside render () or React class */
<Button
title="Update the title"
onPress={() => navigation.setOptions({ title: 'Updated!' })}
/>
Customizing Styles
There are three key properties to use when customizing the header style: headerStyle
, headerTintColor
and headerTitleStyle
.
headerStyle
: a style object to be applied to theView
that wraps the header. If you set it tobackgroundColor
, this will be the color of your title.headerTintColor
: The back button and header use this property as the color. In the example below, we are setting the shade color#fff
to white, so the back button and title heading will be white.headerTitleStyle
: If we want to customize thefontFamily
,fontWeight
and other text style properties for the title, we can use that for that.
There are a few things to note here:
- On iOS, the status bar text and icons are black and it doesn't look good on a dark background. We won't discuss this here, but you should make sure to customize the status bar to match the screen colors as described in the status bar guide.
- The configuration we set applies only to the main screen; when we go to the detail screen, the default styles are returned. We will now look at how to split the
options
between screens.
Sharing shared parameters across screens
There is often a desire to customize the title in the same way on many screens. For example, your company's brand color might be red, so you want the header background color to be red and the tint color to be white. For convenience, these are the colors we are using in our current example, and you will notice that when you go to the DetailsScreen, the colors revert to their defaults. Wouldn't it be awful if we had to copy the options header style properties from HomeScreen to DetailsScreen and for every single screen component we use in our application? Fortunately, no. Instead, we can move the configuration to the stack navigator in the prop screenOptions
section.
Now any screen owned by StackScreen
will have our great branding. Surely there must be a way to override these parameters if we need to?
Replacing the title with a custom component
Sometimes you need more control than just changing the text and heading styles - for example, you might want to display an image instead of a heading, or turn the heading into a button. In these cases, you can completely override the component used for the header and provide your own.
const LogoTitle = () => {
return (
<Image
style={{ width: 50, height: 50 }}
source={require('@expo/snack-static/react-native-logo.png')}
/>
);
}
const StackScreen = () => {
return (
<Stack.Navigator>
<Stack.Screen
name="Home"
component={HomeScreen}
options=options={{ headerTitle: props => <LogoTitle /> }} /> }}
/>
</Stack.Navigator>
)
}
You might be wondering why headerTitle when we provide a component and not a title
like before? The reason is that title
is a stack navigator-specific property, and the default headerTitle
is the Text component that renders title
.
Additional configuration
You can read the full list of available options for screens inside the stack navigator in the reference createStackNavigator.
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.
Links
Contributors ✨
Thanks goes to these wonderful people (emoji key):
Dmitriy Vasilev 💲 |