As a rookie, I started rn soon, but found that the Chinese documents of React-Navigation were quite old and I could not refer to many of them, so I wanted to share the problems I encountered to help others

I used the MAC Mini to develop react-Native 0.63 @react-Navigation /native 5.9.4. Please refer to the official documentation for details, but only the English version can be seen with some difficulties

React-navigation is a great feature and has been updated to pre-6.x 5.9 and has changed in many areas. 90% of the tutorials for React-Navigation are pre-5.x

The installation

yarn add @react-navigation/native

yarn add react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context @react-native-community/masked-view

npx pod-install ios
Copy the code

All three have to be installed and I didn’t install them the first time and I’ve been trying to figure out why

React Native 0.60 and above automatically link to the library. You don’t need to manually run the React Native Link, but if you’re developing for iOS with React Native, you’ll need to manually install pods to link to the library:

npx pod-install ios
Copy the code

If you need a gesture library add import ‘react-native Gesture-handler ‘to the top of the entry file index.js or app.js.

import 'react-native-gesture-handler';
import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';

export default function App() {
  return (
    <NavigationContainer>{/* Rest of your app code */}</NavigationContainer>
  );
}
Copy the code

If you are using the Redux framework, place the Provider in the outermost layer and the NavigationContainer in the second layer, like this:

export default class App(a){
  return (
    <Provider store={store}>
      <NavigationContainer>
        {/* Screen configuration */}
      </NavigationContainer>
    </Provider>
  );
}
Copy the code

Navigation classification

  1. StackNavigator stack navigation can be understood as a header navigation bar
  2. A TabNavigator can be interpreted as a bottom navigation bar
  3. DrawerNavigator drawer navigation can be understood as sliding out of popovers left and right

Since I’m only using StackNavigator, I’m going to focus on StackNavigator and the other two are pretty much the same

yarn add @react-navigation/stack
Copy the code
// In App.js in a new project

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

function HomeScreen (props) {
  return <View style={{ flex: 1.alignItems: 'center', justifyContent: 'center' }}><Button
    title="Go to Login... again"
    onPress={()= > props.navigation.navigate('Login')}
  /></View>
}

function LoginScreen () {
  return <View style={{ flex: 1.alignItems: 'center', justifyContent: 'center' }}><Text>Home</Text></View>
}

const Stack = createStackNavigator();

function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen name="Home" >
          {props => <HomeScreen {. props} / >}  
        </Stack.Screen>
        <Stack.Screen name="Login" component={LoginScreen} /> 
      </Stack.Navigator>
    </NavigationContainer>
  );
}

export default App;
Copy the code

The first stack.screen page is selected as the home page by default

The following are some of his common parameter configurations

Stack.navigator configuration options

      <Stack.Navigator
           initialRouteName="Home"// Initial page
        screenOptions={{
          title: 'Test title'.// Initial page title
          headerStyle: {
            backgroundColor: 'green'// Navigation bar background color
          },
          headerTintColor: '#fff'.// Navigation bar font color
          headerTitleStyle: {
            fontWeight: 'bold'.fontSize: 20
          }
        }}
        keyboardHandlingEnabled={true} // If false, the on-screen keyboard will not close automatically when navigating to a new screen. The default is true
        mode="card"
        /* Define render and transition styles card: Use standard iOS and Android screen transitions. Modal: This does two things: set headerMode to screen stack, unless specified to slide the screen in from the bottom of the bottom of iOS, which is a common iOS mode
        headerMode="none"
        /* Specifies how the title is rendered float: Renders a single title that stays at the top and animates when the screen changes. Common mode on iOS. Screen: Each screen has an additional title that fades in and out with the screen. Common patterns on Android. None: No title. * /
      >
Copy the code

Stack.screen configuration options

    <Stack.Screen
          name="Login"
          component={LoginScreen}
          options={{  // Configure the screens in the navigator
            title: 'My Login'./ / name
            headerShown: true.// Whether to display the name
            headerTitle: <View><Text>Custom header components</Text></View>.// Customize the navigation bar name content
            headerTitleAlign: "left".// Align titles. The value can be left or Center. The default values are ios-center and Android-left
            headerTitleAllowFontScaling: false.// Whether the header header font should be scaled to fit the text Size helper setting. The default is false
            headerBackAllowFontScaling: false.// Whether the back button title font should be scaled to fit the text Size helper setting. The default is false.
            //headerBackImage: 
            headerBackTitle: "Custom Back button text".// The title string used by the back button on iOS. The default is headerTitle of the previous scenario.
            headerBackTitleVisible: true.// provides a reasonable default value for whether the back button title is visible, but you can use true or false in this option if you want to override it
            headerRight: () = > (<View><Text>Custom content on the right of the title</Text></View>),
            / / headerLeft: () = > (< View > < Text > title on the left side of the custom content < / Text > < / View >),
            headerTitleStyle: { backgroundColor: 'orange'.color: '#fff' },// The style object for the title
            // headerTitleStyle
            // headerBackTitleStyle
            // headerLeftContainerStyle
            // headerRightContainerStyle}} / >Copy the code

The above sounds very practical, but in practice it is difficult to satisfy the UI design. Maybe I am too lazy to use the official navigation at the top of my project because there are too many UI navigation styles

A jump animation

You can also configure page jump animation to provide too many self-look-up methods

const config = {
  animation: 'spring'.config: {
    stiffness: 1000.damping: 500.mass: 3.overshootClamping: true.restDisplacementThreshold: 0.01.restSpeedThreshold: 0.01,}};<Stack.Screen
  name="Profile"
  component={Profile}
  options={{
    transitionSpec: {
      open: config.close: config,}}} / >
//forHorizontalIOS Standard ios style slides in from the right
//forVerticalIOS standard ios style slides in from the bottom
/ / forModalPresentationIOS iOS 13 standard iOS modal animation style
/ / forFadeFromBottomAndroid fade in the bottom of the standard Android style
/ / forRevealFromBottomAndroid standard Android style of Android at the bottom of the display

import { CardStyleInterpolators } from '@react-navigation/stack';

<Stack.Screen
  name="Profile"
  component={Profile}
  options={{
    title: 'Profile',
    cardStyleInterpolator: CardStyleInterpolators.forFadeFromBottomAndroid,
  }}
/>;
Copy the code

Navigation jump mode (key)

function HomeScreen({ navigation }) {
  return (
    <View style={{ flex: 1.alignItems: 'center', justifyContent: 'center' }}>
      <Text style={{ fontSize: 30}} >This is the home screen!</Text>
      <Button
        onPress={()= > navigation.navigate('Login')}
        title="Open Modal"
      />
    </View>
  );
}
this.props.navigation.navigate("Login", {id:xxxx})
this.props.navigation.push("Login", {id:xxxx})
this.props.navigation.replace("Login", {id:xxxx})
this.props.navigation.goBack()
this.props.navigation.goBack("Login")
this.props.navigation.pop()
this.props.navigation.pop(n) //n indicates the level of the page to return to
this.props.navigation.popToTop()

const id=this.props.route.params.id
Copy the code
  1. Navigate enters the new page of the stack
  2. Push the new page
  3. Replace Replace the current page (to be paid to be paid to complete the page back without to be paid to be used)
  4. GoBack One page back to close the current page
  5. Pop returns to the previous page by default
  6. PopToTop returns to the topmost page

Navigate, push, and replace

If there is no B page in the stack, give or take the same operation as give or give for push. If there is no B page in the stack, give or take for push. If a page is already in the stack, give no error, but no navigate is given because B is already in the stack. The new B page is only pushed using push. Now that we have an understanding of the difference between navigate and push, see the figure above for a sequence of inputputations that give the final shape of the navigate stack. The three scenarios are discussed below.

Now we are on page C, and if C pushes A, it will also continue to navigate A, but if C navigate A is used, all of the above pages will be pushed out, equivalent to popToTop, to return to page A.

2. The page is now in C, if push B, C will also B to continue into the stack, but at the moment, if use navigate B, C are the current C began looking for B interface down, until you find the nearest B interface, jump, C and B all the stack in the middle of the page, at this point B can also continue to return, return to A page step by step;

If the app receives A push and clicks on it to navigate to A new BrowserPage, it will be unable to navigate if the logic for the current page is to use the navigate method. Because BrowserPage is already on the stack (just browsing the web), we use the push method here;

A receives A notification to navigate to THE interface of C, where C pushes in and overwrites B. If C clicks back, it will return to THE interface of B, as C has performed an exit operation to reach B instead of returning to A.

5. The replace method,

Replace-replace the current route with a new one is to replace the current route with a new page, so that a navigate to B, After B completes the task, C returns A instead of B. In this case, B replaces C to fulfill the requirement.

From www.cnblogs.com/li-wei203/p… I thought it was pretty good so I brought it in

Listening navigation (key)

This uses a high probability of sliding back to redirect routes or sliding back to leave the page blocking prompt

1. Focus – This event is emitted when the screen is in focus

Blur – This event is emitted when the screen is out of focus

3. BeforeRemove (Version 5.7+ only) – (above version 5.7)- Prevents the user from leaving the screen when the user leaves

4. State (Advanced)- This event is emitted when the state of the navigator changes

5. TabPress (Advanced) – Listens for TAB page switching

const unsubscribe = navigation.addListener('tabPress'.e= > {
  // Prevent default action
  e.preventDefault();
});

function Profile({ navigation }) {
  React.useEffect(() = > {
    const unsubscribe = navigation.addListener('focus'.() = > {
      // do something
    });

    return unsubscribe;
  }, [navigation]);

  return <ProfileContent />; } or < tab.screen name="Chat"
  component={Chat}
  listeners={({ navigation, route }) = > ({
    tabPress: e= > {
      // Prevent default action
      e.preventDefault();

      // Do something with the `navigation` object
      navigation.navigate('AnotherPlace'); }})} / >Copy the code

There is also a way to prevent the back button event on the screen back device by calling your own function to handle the back behavior. This API is only available on Android.

import React, { Component } from "react";
import { Text, View, StyleSheet, BackHandler, Alert } from "react-native";

class App extends Component {
  backAction = () = > {
    Alert.alert("Hold on!"."Are you sure you want to go back?"[{text: "Cancel".onPress: () = > null.style: "cancel"
      },
      { text: "YES".onPress: () = > BackHandler.exitApp() }
    ]);
    return true;
  };

  componentDidMount() {
    BackHandler.addEventListener("hardwareBackPress".this.backAction);
  }

  componentWillUnmount() {
    BackHandler.removeEventListener("hardwareBackPress".this.backAction);
  }

  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.text}>Click Back button!</Text>
      </View>); }};const styles = StyleSheet.create({
  container: {
    flex: 1.alignItems: "center".justifyContent: "center"
  },
  text: {
    fontSize: 18.fontWeight: "bold"}});export default App;
});
Copy the code

I don’t know what I wrote in this long article for the first time, but the react-navigation is a lot of stuff… It feels like rn isn’t even written anymore and everyone is pushing flutter and using it