The react – native navigator

1. Install dependencies

npm install @react-navigation/native
npm install react-native-gesture-handler 
npm install react-native-reanimated 
npm install react-native-screens 
npm install react-native-safe-area-context 
npm install @react-native-community/masked-view

// yarn Uses yarn add
Copy the code

React Native 0.60 and later, links are automatic. Therefore, there is no need to run the React-Native link

If you’re on a Mac and developing for iOS, you’ll need to install Pad (via Cocoapods) to complete the linking

npx pod-install ios
Copy the code

Copy the following code from app.js or index.js

import 'react-native-gesture-handler';
Copy the code

2. Create a Stack Navigation

2.1 Installing stack navigation dependencies

npm install @react-navigation/stack
Copy the code

2.2 Navigation available apis

Navigation properties can be obtained in all page components (as long as the component is defined to route configuration and render routes using React Navigation).

// const {route, navigation} = this.props; / / class
/ / available API
navigation.navigate("RouteName") // If the new route is not on the stack, it is pushed to the stack navigator, otherwise it is redirected to this page.
navigation.push("RouteName") // Redirect to a route page You can redirect to the same route page for multiple times
navigation.goBack() // Return to the previous page
navigation.popToTop() // Return to the first screen page of the stack
navigation.popToTop() // Return to the first screen page of the stack
navigation.popToTop() // Return to the first screen page of the stack

Copy the code

2.3 Example

// In App.js in a new project

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 LoginScreen({navigation}) {
  return (
    <View style={{ flex: 1.alignItems: 'center', justifyContent: 'center' }}>
      <Text>Login Screen</Text>
      <Button title="User Login" onPress={()= > navigation.navigate("Home")}></Button>
    </View>
  );
}
function HomeScreen({navigation}) {
  return (
    <View style={{ flex: 1.alignItems: 'center', justifyContent: 'center' }}>
      <Text>Home Screen</Text>
      <Button title="Home Page" onPress={()= > navigation.navigate("Login")}></Button>
    </View>
  );
}

const Stack = createStackNavigator();
// Want to hide the first header navigation
// <Stack.Screen name="Login" options={{headerShown: false}} component={LoginScreen} />

function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator>// options={({route}) => ({title: route.params.name})} // Header navigation can be dynamically modified based on route parameters<Stack.Screen name="Login" component={LoginScreen} />
        <Stack.Screen name="Home" component={HomeScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

export default App;
Copy the code

2.4 Setting stack navigation animation

Built in the corresponding jump animation

  1. forHorizontal: Enter from right to left
  2. forVertical: Enters from the bottom up
  3. forFadeFromBottomAndroid: Fades out from the bottom
  4. forFadeNo animation:
function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen name="Login" component={LoginScreen} />// Home page to add animation from right to left<Stack.Screen name="Home" component={HomeScreen}  options={{headerShown: false.cardStyleInterpolator: CardStyleInterpolators.forHorizontalIOS}} / >
      </Stack.Navigator>
    </NavigationContainer>
  );
}
Copy the code

Each time push is invoked, we add a new route to the navigation stack. When you invoke navigation, it first tries to find an existing route with that name, and pushes a new route only if there are no new routes on the stack.

This completes a stack navigation and allows for page-like switching between login and registration.

2.5 Parameter Transfer for Navigator (Route)

2.5.1 Parameters nested in the navigation

Put the required parameters of the route in an object as the second parameter of the navigation.navigate function: navigation.navigate(‘RouteName’, {key: Value}), get this parameter in the component: route.params.

navigation.navigate('Home', {
  screen: 'Settings'.params: { user: 'Tom'}});Copy the code
2.5.2 Updating Parameters

Parameters can also be updated on the page, similar to updating the page status. Navigation. SetParams can be used to update page parameters

You can also pass some initial parameters to the page. If you navigate to the page without setting any parameters, this initial parameter will be used. They are shallow merged with the passed parameters. The initial parameter is specified as the initialParams property:

<Stack.Screen
  name="Login"
  component={Login}
  initialParams={{ userId: 42}} / >Copy the code
2.5.3 Passing Parameters to previous pages

You can pass parameters not only to the new page, but also to the previous page.

To do this, you can use the navigate method or, if the page exists, a method like goBack. You can return the parameter with the navigate parameter:

// Some.js
import React, { useState, Component } from "react";
import { Text, View } from "react-native";

class App extends Component {
  constructor(props) {
    super(props)
  }
  render() {
    return (
      <View>
       <Text>{this.props.route.params.type ? this.props.route.params.type : "has null"}</Text>
      </View>)}}export default App;
Copy the code
// Home.js
import * as React from 'react';
import { View, TextInput, Button } from 'react-native';
function goLogin(navigation, postText) {
  navigation.push("Login", {type: postText}) // Pass the input field value to the Login page
}
function Some({navigation, route}) {
  let {text} = route.params;
  let [postText, setPostText] = React.useState(text);
  return (
    <View>
      <TextInput
        multiline
        placeholder="What's on your mind?"
        style={{ height: 200.padding: 10.backgroundColor: 'gray'}}value={postText}
        onChangeText={setPostText}
      />
      <Button
        title="Go to Login"
        onPress={()= > goLogin(navigation, postText)}
      />
    </View>
  );
}
export default Some;
Copy the code

2.6 Configuring the Header Bar

The custom header style has three key attributes: headerStyle, headerTintColor, and headerTitleStyle.

function App() {
  return (
    <NavigationContainer>
        <Stack.Navigator>
          <Stack.Screen
            name="Home"
            component={Home}
            options={{
              title: 'My home',
              headerStyle: {
                backgroundColor: '#f4511e'},headerTintColor: '#fff',
              headerTitleStyle: {
                fontWeight: 'bold',}}} / >
        </Stack.Navigator>
    </NavigationContainer>
  );
}
Copy the code

2.7 the Header Button

Add an action button to the right of the header — a common feature

function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator initialRouteName="Login">
        <Stack.Screen options={{headerShown: false}}  name="Login"  component={Login} />
        <Stack.Screen name="Some" component={Some} 
          options={{
            headerRight:() = > (
              <Button
                onPress={()= >alert('This is a button! ')} title="add" color="#999" /> ), }} /></Stack.Navigator>
    </NavigationContainer>
  );
}
Copy the code

3. Nested Tabs

3.1 Installation Dependencies

npm install @react-navigation/bottom-tabs / / 5. X version
Copy the code

3.2 Example

// some.js // Replace the previous some.js with the following code
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
import * as React from 'react';
import { View, Button, Text } from 'react-native';

const Tab = createBottomTabNavigator(); // 

function HomePage() {
  return (
    <View
      style={{
        flex: 1.backgroundColor: '#ccc',
        justifyContent: 'center',
        alignItems: 'center'}} >
      <Text>HomePage</Text>
      <Button
        title="Go to Profile"
        onPress={()= > navigation.push('Login')}
      />
    </View>
  );
}

function Detail({navigation}) {
  return (
    <View
      style={{
        flex: 1.backgroundColor: '#ddd',
        justifyContent: 'center',
        alignItems: 'center'}} >
      <Text>Detail</Text>
    </View>
  );
}
function Mine({navigation}) {
  return (
    <View
      style={{
        flex: 1.backgroundColor: '#ddd',
        justifyContent: 'center',
        alignItems: 'center'}} >
      <Text>Mine</Text>
    </View>
  );
}
function Some({navigation, route}) {
  return (
    <Tab.Navigator>
      <Tab.Screen name="HomePage" component={HomePage} />
      <Tab.Screen name="Detail" component={Detail} />
      <Tab.Screen name="Mine" component={Mine} />
    </Tab.Navigator>
  );
}
export default Some;
Copy the code

3.3 Adding an Icon to a Tab

The first kind of

function TabNav() {
  return (
      <Tab.Navigator
        initialRouteName="HomePage"
        screenOptions={({ route}) = > ({
          tabBarIcon: ({ focused, color, size }) => {
            let icon;
            if (route.name === 'HomePage') {
              icon = focused
                ? require("@/assets/images/icon_tab1_active.png")
                : require("@/assets/images/icon_tab1.png");
            } else
             if (route.name === 'Detail') {
              icon = focused
                ? require("@/assets/images/icon_tab2_active.png")
                : require("@/assets/images/icon_tab2.png");
            }else if (route.name === 'Mine') {
              icon = focused
                ? require("@/assets/images/icon_tab3_active.png")
                : require("@/assets/images/icon_tab3.png");
            }
            return <Image style={styles.tabImg} source={icon}></Image>}})} ><Tab.Screen name="HomePage" component={Home} />
        <Tab.Screen name="Detail" component={Geo} />
        <Tab.Screen name="Mine" component={Mine} />
        
      </Tab.Navigator>
  );
}
Copy the code

The second reactnavigation.org/docs/bottom…


function MyTabBar({ state, descriptors, navigation }) {
  const focusedOptions = descriptors[state.routes[state.index].key].options;

  if (focusedOptions.tabBarVisible === false) {
    return null;
  }

  return (
    <View style={{ flexDirection: 'row' }}>{ state.routes.map((route, index) => { const { options } = descriptors[route.key]; const label = options.tabBarLabel ! == undefined ? options.tabBarLabel : options.title ! == undefined ? options.title : route.name; const isFocused = state.index === index; let icon; if (label === 'HomePage') { icon = isFocused ? require("@/assets/images/icon_tab1_active.png") : require("@/assets/images/icon_tab1.png"); } else if (label === 'Detail') { icon = isFocused ? require("@/assets/images/icon_tab2_active.png") : require("@/assets/images/icon_tab2.png"); }else if (label === 'Mine') { icon = isFocused ? require("@/assets/images/icon_tab3_active.png") : require("@/assets/images/icon_tab3.png"); } const onPress = () => { const event = navigation.emit({ type: 'tabPress', target: route.key, canPreventDefault: true, }); if (! isFocused && ! event.defaultPrevented) { navigation.navigate(route.name); }}; const onLongPress = () => { navigation.emit({ type: 'tabLongPress', target: route.key, }); }; return (<TouchableOpacity
              activeOpacity=0.8} {
              accessibilityRole="button"
              accessibilityState={isFocused ? { selected: true } : {}}
              accessibilityLabel={options.tabBarAccessibilityLabel}
              testID={options.tabBarTestID}
              onPress={onPress}
              onLongPress={onLongPress}
              style={{ flex: 1.paddingBottom: 8.paddingTop:8.flexDirection:"column",justifyContent:"center",alignItems:"center", backgroundColor:"#fff}} ">
              
              <TouchableOpacity activeOpacity=0.8} { onPress={onPress}>
                <Image style={{ width: 18.height: 18 }} source={icon}></Image>
              </TouchableOpacity>
              <Text style={{ color: isFocused ? '#5095fb' : 'gray' }}>
                {label}
              </Text>
            </TouchableOpacity>); })}</View>
  );
}

function Some({navigation, route}) {
  return (
    <Tab.Navigator
        tabBar={props= > <MyTabBar {. props} / >}
    >
      <Tab.Screen name="HomePage" component={HomePage} />
      <Tab.Screen name="Detail" component={Detail} />
      <Tab.Screen name="Mine" component={Mine} />
    </Tab.Navigator>
  );
}
export default Some;
Copy the code

3.4 Listening for Tab Clicks

class Home extends Component {
    constructor(props) {
        super(props)
    }
    componentDidMount() {
        // focus 或者 blur
        this._navListener = this.props.navigation.addListener('focus'.() = > {
            console.log("Clicked");
        });
    }
    componentWillUnmount() {
        this._navListener.remove(); }}Copy the code