This is the 10th day of my participation in the August More Text Challenge. For details, see:August is more challenging
Properties in options:
-
Public Settings across pages
<Stack.Navigator screenOptions={{ headerStyle: { backgroundColor: '#f4511e',},headerTintColor: '#fff'.headerTitleStyle: { fontWeight: 'bold',}}} ><Stack.Screen name="Home" component={HomeScreen} options={{ title:}} /> </Stack.Navigator> Copy the code
-
Title: the title
<Stack.Navigator> <Stack.Screen name="Home" component={HomeScreen} options={{ title:}} /> </Stack.Navigator> Copy the code
-
Use the title passed by the parameter
The argument passed to the options function is an object with the following properties:
Navigation – The navigation of the page
Route – The route of the page;
<Stack.Navigator> <Stack.Screen name="Home" component={ProfileScreen} options={({ route}) = > ({ title: route.params.name })} /> </Stack.Navigator> Copy the code
-
SetOptions () sets the properties on the Tabbar component
navigation.setOptions({ title: 'Updated! ' }) Copy the code
-
Header header
-
HeaderStyle sets the header headerStyle
headerStyle: { backgroundColor: 'red',},Copy the code
-
HeaderTinColor: Sets the header title bar font color
-
HeaderTitleStyle: Sets the header header style
headerTitleStyle: { fontWeight: 'bold'.fontSize: 30,},Copy the code
-
-
Custom header header bar
headerTitle
Custom header text that can be passed to a componentheaderBackTitleVisible
Whether to display the text for the return buttonheaderBackTitle
Sets the text for the return buttonheaderRight
Sets the style to the right of the header header to pass a componentheaderBackImage
Custom return icon that returns a picture component
Nesting a navigator means rendering a navigator on the screen of another navigator; In general, the home page will have a Tabbar bar, as follows:
import React, { Component } from 'react';
import { NavigationContainer } from '@react-navigation/native';
import {
createStackNavigator,
HeaderBackButton,
StackNavigationProp,
} from '@react-navigation/stack';
import Found from '.. /pages/found/Found';
import List from '.. /pages/list/List';
import Me from '.. /pages/me/Me';
import BottomTabs from './ButtomTab';
import Detail from '.. /pages/detail/Detail';
import Login from '.. /pages/login/Login';
import Search from '.. /pages/search/Search';
import Play from '.. /pages/play/Play';
import MVPlay from '.. /pages/mv-play/MVPlay';
import CustomTitleBar from '.. /pages/custom-title-bar/CustomTitleBar';
import CustomHeader from '.. /components/CustomHeader';
import { Button } from '@ant-design/react-native';
import { Alert, Image } from 'react-native';
export type RootStackParamList = {
BottomTabs: undefined;
List: undefined;
Found: undefined;
Me: undefined;
Login: undefined;
Detail: {
topId: number;
};
Search: undefined;
Play: {
id: number;
};
MVPlay: {
vid: string;
};
CustomTitleBar: undefined;
};
export type RootStackNavigation = StackNavigationProp<RootStackParamList>;
const Stack = createStackNavigator<RootStackParamList>();
export default class Navigator extends Component {
render() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="BottomTabs"
component={BottomTabs}
options={{
headerTitle:'home',headerStyle: {
backgroundColor: 'red'},headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
fontSize: 30,}}} / >
<Stack.Screen
name="List"
component={List}
options={{ headerTitle:}} />
<Stack.Screen
name="Found"
component={Found}
options={{ headerTitle:'discover'}} />
<Stack.Screen
name="Me"
component={Me}
options={{ headerTitle:'my'}} />
<Stack.Screen
name="Login"
component={Login}
options={{ headerTitle:'Login'}} />
<Stack.Screen
name="Detail"
component={Detail}
options={{ headerTitle:'Playlist'}} />
<Stack.Screen
name="Search"
component={Search}
options={{ headerTitle:'search'}} />
<Stack.Screen
name="Play"
component={Play}
options={{ headerTitle:'Song'}} />
<Stack.Screen
name="MVPlay"
component={MVPlay}
options={{ headerTitle: 'mv' }}
/>
<Stack.Screen
name="CustomTitleBar"
component={CustomTitleBar}
options={{
headerTitle: (props) = > <CustomHeader {. props} / >,
// headerBackTitleVisible: false,
headerBackTitle: '1234',
headerRight: () => (
<Button onPress={()= > Alert.alert('right')}>
right
</Button>
),
headerBackImage: () => (
<Image
source={{
uri: 'https://qpic.y.qq.com/music_cover/DhpicvGxCZozibtVUC0Q03Oia0h9DnKUNHPdPL3oD2tqUJiaYJUv1jvlEXbPvCCy4Vql/300?n=1'}}style={[
{
width: 60.height: 60.marginRight: 20,},]} / >
),
}}
/>
</Stack.Navigator>
</NavigationContainer>); }}Copy the code
The complete code is as follows:
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import React, { Component } from 'react';
import {
getFocusedRouteNameFromRoute,
RouteProp,
TabNavigationState,
} from '@react-navigation/native';
import { RootStackNavigation, RootStackParamList } from './index';
import Home from '.. /pages/home/Home';
import List from '.. /pages/list/List';
import Found from '.. /pages/found/Found';
import Me from '.. /pages/me/Me';
export type BottomTabParamList = {
Home: undefined;
List: undefined;
Found: undefined;
Me: undefined;
};
const Tab = createBottomTabNavigator<BottomTabParamList>();
type Route = RouteProp<RootStackParamList, 'BottomTabs'> & { state? : TabNavigationState<BottomTabParamList>; };interface IProps {
navigation: RootStackNavigation;
route: Route;
}
export default class BottomTabs extends Component<IProps> {
// Get the title of each page
getHeaderTitle(route: Route): string {
const routeName = getFocusedRouteNameFromRoute(route) ?? 'Home';
switch (routeName) {
case 'Home':
return 'home';
case 'List':
return 'list';
case 'Found':
return 'found';
case 'Me':
return 'I';
default:
return 'home'; }}componentDidUpdate() {
const { navigation, route } = this.props;
navigation.setOptions({
headerTitle: this.getHeaderTitle(route),
});
}
render() {
return (
<Tab.Navigator
tabBarOptions={{
activeTintColor: '#f86442', / / modifytabbarActivate color}}>
<Tab.Screen
name="Home"
component={Home}
options={{ tabBarLabel:}} />
<Tab.Screen
name="List"
component={List}
options={{ tabBarLabel:}} />
<Tab.Screen
name="Found"
component={Found}
options={{ tabBarLabel:'discover'}} />
<Tab.Screen
name="Me"
component={Me}
options={{ tabBarLabel:'my'}} />
</Tab.Navigator>); }}Copy the code
There is a bottom tabbar for the home page, lists, Find, and my pages. This is an embedded function. The component with the Tabbar is loaded for the first time. Click on the tabbar button to switch.
React Navigation life cycle
We used a stack navigator with two screens (Home and Detail) and learned how to navigate between routes with navigation.navigate(‘RouteName’).
In this case, an important question is: What happens to Home when we leave it, or when we return to it? How does the route find out if the user is leaving it or returning it?
If you’re going to do reactive navigation from a Web background, you can assume that when the user navigates from route A to route B, A will be unloaded (its componentWillUnmount is called) and A will be loaded again when the user returns to it. While these React lifecycle methods are still valid and used in React-Navigation, their usage is different from the Web. This is driven by the more complex requirements of mobile navigation.
For example, a stack navigator with screens A and B. After navigating to A, call its componentDidMount. When B is pushed, its componentDidMount is also called, but A is still mounted on the stack, so its componentWillUnmount is not called.
When returning from B to A, B’s componentWillUnmount is called, but A’s componentDidMount is not called, because A keeps mounting; Similar results can be combined with nested navigation. Consider a tag navigator with two tags, each of which is a stack navigator:
import * as React from 'react';
import { Button, View, Text } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
function SettingsScreen({ navigation }) {
return (
<View
style={{ flex: 1.alignItems: 'center', justifyContent: 'center' }}>
<Text>Settings Screen</Text>
<Button
title="Go to Profile"
onPress={()= > navigation.navigate('Profile')}
/>
</View>
);
}
function ProfileScreen({ navigation }) {
return (
<View
style={{ flex: 1.alignItems: 'center', justifyContent: 'center' }}>
<Text>Profile Screen</Text>
<Button
title="Go to Settings"
onPress={()= > navigation.navigate('Settings')}
/>
</View>
);
}
function HomeScreen({ navigation }) {
return (
<View
style={{ flex: 1.alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
<Button
title="Go to Details"
onPress={()= > navigation.navigate('Details')}
/>
</View>
);
}
function DetailsScreen({ navigation }) {
return (
<View
style={{ flex: 1.alignItems: 'center', justifyContent: 'center' }}>
<Text>Details Screen</Text>
<Button
title="Go to Details... again"
onPress={()= > navigation.push('Details')}
/>
</View>
);
}
const Tab = createBottomTabNavigator();
const SettingsStack = createStackNavigator();
const HomeStack = createStackNavigator();
export default function App() {
return (
<NavigationContainer>
<Tab.Navigator>
<Tab.Screen name="First">{() = > (<SettingsStack.Navigator>
<SettingsStack.Screen
name="Settings"
component={SettingsScreen}
/>
<SettingsStack.Screen
name="Profile"
component={ProfileScreen}
/>
</SettingsStack.Navigator>
)}
</Tab.Screen>
<Tab.Screen name="Second">{() = > (<HomeStack.Navigator>
<HomeStack.Screen
name="Home"
component={HomeScreen}
/>
<HomeStack.Screen
name="Details"
component={DetailsScreen}
/>
</HomeStack.Navigator>
)}
</Tab.Screen>
</Tab.Navigator>
</NavigationContainer>
);
}
Copy the code
We went from HomeScreen to DetailScreen and then used the TAB bar to switch to SetterScreen and navigate to profileScreen. After that, we mounted the 4 screen components. If you use the TAB bar to switch back to HomeStack, You’ll notice that the detailsScreen-Homestack navigation state is preserved!
React Navigation declares events in the cycle
Foucs listens for focusing events; The focus event of the HTML input tag does the same thing
Blur listens for events beyond focus. The blur event on the HTML input tag does the same thing
function Profile({ navigation }) {
React.useEffect(() = > {
const unsubscribe = navigation.addListener('focus'.() = > {
// Screen was focused
// Do something
});
return unsubscribe;
}, [navigation]);
return <ProfileContent />;
}
Copy the code
The useFoucsEffect hook function can be used in function components to listen for execution events
import { useFocusEffect } from '@react-navigation/native';
function Profile() {
useFocusEffect(
React.useCallback(() = > {
// Do something when the screen is focused
return () = > {
// Do something when the screen is unfocused
// Useful for cleanup functions}; } []));return <ProfileContent />;
}
Copy the code