【问题标题】:Deep Linking in Nested Navigators in react navigation反应导航中嵌套导航器中的深度链接
【发布时间】:2018-10-18 01:51:03
【问题描述】:

我正在使用 react-navigation,根据我的应用程序的结构,我们在堆栈导航器中有一个选项卡导航器,我无法找到任何合适的实现深度链接的指南。

https://v1.reactnavigation.org/docs/deep-linking.html。这没有为嵌套导航器提供任何参考。

【问题讨论】:

    标签: react-native


    【解决方案1】:

    您基本上必须将path 传递给每条上层路线,直到您到达嵌套路线。这与您使用的导航器类型无关。

    const HomeStack = createStackNavigator({
        Article: {
            screen: ArticleScreen,
            path: 'article',
        },
    });
    
    const SimpleApp = createAppContainer(createBottomTabNavigator({
        Home: { 
            screen: HomeStack,
            path: 'home',
        },
    }));
    
    const prefix = Platform.OS == 'android' ? 'myapp://myapp/' : 'myapp://';
    
    const MainApp = () => <SimpleApp uriPrefix={prefix} />;
    

    在这种情况下,路由到内部导航器是路由:myapp://home/article

    这个例子使用react-navigation@^3.0.0,但是很容易转移到v1

    【讨论】:

      【解决方案2】:

      所以,在 React Navigation V3 到来之后, 事情变得非常稳定。现在我将在 Switch navigator -> drawerNavigator-> tabNavigator -> stack-> navigator 中向您展示一个带有深度链接的导航结构。请逐步了解结构,并在每一步都参考官方文档

      对于嵌套导航器,人们通常指的是由抽屉导航器、选项卡导航器和堆栈导航器组成的导航结构。在 V3 中,我们也有 SwitchNavigator。所以让我们直接进入代码,

      //here we will have the basic React and react native imports which depends on what you want to render
      import React, { Component } from "react";
      import {
          Platform,
          StyleSheet,
          Text,
          View, Animated, Easing, Image,
          Button,
          TouchableOpacity, TextInput, SafeAreaView, FlatList, Vibration, ActivityIndicator, PermissionsAndroid, Linking
      } from "react-native";
      import { createSwitchNavigator, createAppContainer, createDrawerNavigator, createBottomTabNavigator, createStackNavigator } from "react-navigation";
      
      export default class App extends Component<Props> {
          constructor() {
              super()
              this.state = {
                  isLoading: true
              }
          }
          render() {
              return <AppContainer uriPrefix={prefix} />;
          }
      }
      class WelcomeScreen extends Component {
          state = {
              fadeAnim: new Animated.Value(0.2),  // Initial value for opacity: 0
          }
          componentDidMount() {
              Animated.timing(                  // Animate over time
                  this.state.fadeAnim,            // The animated value to drive
                  {
                      toValue: 1,
                      easing: Easing.back(),                  // Animate to opacity: 1 (opaque)
                      duration: 1000,
                      useNativeDriver: true           // Make it take a while
                  }
              ).start();                        // Starts the animation
          }
      
          render() {
              let { fadeAnim } = this.state;
              return (
                  <View style={{ flex: 1, alignItems: "center", justifyContent: "center", backgroundColor: '#000' }}>
                      <Animated.View                 // Special animatable View
                          style={{ opacity: fadeAnim }}
                      >
                          <TouchableOpacity
                              onPress={() => this.props.navigation.navigate("Dashboard")}
                              style={{
                                  backgroundColor: "orange",
                                  alignItems: "center",
                                  justifyContent: "center",
                                  height: 30,
                                  width: 100,
                                  borderRadius: 10,
                                  borderColor: "#ccc",
                                  borderWidth: 2,
                                  marginBottom: 10
                              }}
                          >
                              <Text>Login</Text>
                          </TouchableOpacity>
                      </Animated.View>
                      <Animated.View                 // Special animatable View
                          style={{ opacity: fadeAnim }}
                      >
                          <TouchableOpacity
                              onPress={() => alert("buttonPressed")}
                              style={{
                                  backgroundColor: "orange",
                                  alignItems: "center",
                                  justifyContent: "center",
                                  height: 30,
                                  width: 100,
                                  borderRadius: 10,
                                  borderColor: "#ccc",
                                  borderWidth: 2
                              }}
                          >
                              <Text> Sign Up</Text>
                          </TouchableOpacity>
                      </Animated.View>
                  </View>
              );
          }
      }
      class Feed extends Component {
          render() {
              return (
                  <View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
                      <Button
                          onPress={() => this.props.navigation.navigate("DetailsScreen")}
                          title="Go to details"
                      />
                  </View>
              );
          }
      }
      class Profile extends Component {
          render() {
              return (
                  <SafeAreaView style={{ flex: 1, }}>
                  //Somecode
                  </SafeAreaView>
              );
          }
      }
      class Settings extends Component {
          render() {
              return (
                  <View style={{ flex: 1 }}>
                  //Some code
                  </View>
              );
          }
      }
      const feedStack = createStackNavigator({
          Feed: {
              screen: Feed,
              path: 'feed',
              navigationOptions: ({ navigation }) => {
                  return {
                      headerTitle: "Feed",
                      headerLeft: (
                          <Icon
                              style={{ paddingLeft: 10 }}
                              name="md-menu"
                              size={30}
                              onPress={() => navigation.openDrawer()}
                          />
                      )
                  };
              }
          },
          DetailsScreen: {
              screen: Detail,
              path: 'details',
              navigationOptions: ({ navigation }) => {
                  return {
                      headerTitle: "Details",
                  };
              }
          }
      });
      const profileStack = createStackNavigator({
          Profile: {
              screen: Profile,
              path: 'profile',
              navigationOptions: ({ navigation }) => {
                  return {
                      headerTitle: "Profile",
                      headerMode: 'Float',
                      headerLeft: (
                          <Icon
                              style={{ paddingLeft: 10 }}
                              name="md-menu"
                              size={30}
                              onPress={() => navigation.openDrawer()}
                          />
                      )
                  };
              }
          },
          DetailsScreen: {
              screen: Detail,
              path: 'details',
              navigationOptions: ({ navigation }) => {
                  return {
                      headerTitle: "Details"
                  };
              }
          }
      });
      const settingStack = createStackNavigator({
          Settings: {
              screen: Settings,
              path: 'settings',
              navigationOptions: ({ navigation }) => {
                  return {
                      headerTitle: "Settings",
                      headerLeft: (
                          <Icon
                              style={{ paddingLeft: 10 }}
                              name="md-menu"
                              size={30}
                              onPress={() => navigation.openDrawer()}
                          />
                      )
                  };
              }
          },
          DetailsScreen: {
              screen: Detail,
              path: 'details',
              navigationOptions: ({ navigation }) => {
                  return {
                      headerTitle: "Details"
                  };
              },
      
          }
      });
      const DashboardTabNavigator = createBottomTabNavigator(
          {
              feedStack: {
                  screen: feedStack,
                  path: 'feedStack',
                  navigationOptions: ({ navigation }) => {
                      let tabBarVisible = true;
                      if (navigation.state.index > 0) {
                          tabBarVisible = false;
                      }
                      return {
                          tabBarLabel: "Feed",
                          tabBarVisible,
                          //iconName :`ios-list${focused ? '' : '-outline'}`,
                          tabBarIcon: ({ tintColor }) => (
                              <Icon name="ios-list" color={tintColor} size={25} />
                          )
                      };
                  }
              },
      
              profileStack: {
                  screen: profileStack,
                  path: 'profileStack',
                  navigationOptions: ({ navigation, focused }) => {
                      let tabBarVisible = true;
                      if (navigation.state.index > 0) {
                          tabBarVisible = false
                      }
                      return {
                          tabBarVisible,
                          tabBarLabel: "Profile",
                          tabBarIcon: ({ tintColor }) => (
                              <Icon name="ios-man" color={tintColor} size={25} />
                          )
                      };
                      // focused:true,
                  }
              },
              settingStack: {
                  screen: settingStack,
                  path: 'settingsStack',
                  navigationOptions: ({ navigation }) => {
                      let tabBarVisible = true;
                      if (navigation.state.index > 0) {
                          tabBarVisible = false;
                      }
                      return {
                          tabBarVisible,
                          tabBarLabel: "Settings",
                          tabBarIcon: ({ tintColor }) => (
                              <Icon name="ios-options" color={tintColor} size={25} />
                          )
                      }
      
                  }
              },
      
          },
          {
              navigationOptions: ({ navigation }) => {
      
                  const { routeName } = navigation.state.routes[navigation.state.index];
                  return {
                      // headerTitle: routeName,
      
                      header: null
                  };
              },
              tabBarOptions: {
                  //showLabel: true, // hide labels
                  activeTintColor: "orange", // active icon color
                  inactiveTintColor: "#586589" // inactive icon color
                  //activeBackgroundColor:'#32a1fe',
              }
          }
      );
      const DashboardStackNavigator = createStackNavigator(
          {
              DashboardTabNavigator: {
                  screen: DashboardTabNavigator,
                  path: 'dashboardtabs'
              },
              DetailsScreen: {
                  screen: Detail,
                  path: 'details',
                  navigationOptions: ({ navigation }) => {
                      return {
                          headerTitle: "Details"
                      };
                  }
              }
          },
          {
              defaultNavigationOptions: ({ navigation }) => {
                  return {
                      headerLeft: (
                          <Icon
                              style={{ paddingLeft: 10 }}
                              name="md-menu"
                              size={30}
                              onPress={() => navigation.openDrawer()}
                          />
                      )
                  };
              }
          }
      );
      const AppDrawerNavigator = createDrawerNavigator({
          Dashboard: {
              screen: DashboardStackNavigator,
              path: 'welcome'
          },
          DetailsScreen: {
              screen: Detail,
              path: 'friends',
              navigationOptions: ({ navigation }) => {
                  return {
                      headerTitle: "Details",
      
                  };
              }
          }
      });
      //Switch navigator , will be first to load
      const AppSwitchNavigator = createSwitchNavigator({
          Welcome: {
              screen: WelcomeScreen,
      
          },
          Dashboard: {
              screen: AppDrawerNavigator,
              path: 'welcome'
          }
      });
      const prefix = 'myapp://';
      const AppContainer = createAppContainer(AppSwitchNavigator);
      

      有关设置 React-navigation 深度链接的过程,请关注official documentation

      DetailsS​​creen 位于我的不同文件夹中,其中包含您选择的类组件

      要启动应用程序,深层链接 URL 是 myapp://welcome

      要转到根页面,深层链接 URL 是 myapp://welcome/welcome (这将到达标签导航器第一个标签的第一页)

      转到选项卡导航器的任何特定屏幕(假设详细信息 个人资料选项卡中的屏幕)- myapp://welcome/welcome/profileStack/details

      【讨论】:

        【解决方案3】:
            const config = {
          Tabs: {
            screens: {
              UserProfile: {
                path: 'share//user_share/:userId',
                parse: {
                  userId: (userId) => `${userId}`,
                },
              },
            },
          },
        };
        
        const linking = {
          prefixes: ['recreative://'],
          config,
        };
        

        如果您在选项卡导航器中有一个屏幕,您可以通过 react-navigation v5 这样做

        【讨论】:

          猜你喜欢
          • 2021-08-28
          • 2021-11-07
          • 1970-01-01
          • 2019-02-17
          • 1970-01-01
          • 1970-01-01
          • 2020-08-01
          • 2020-11-05
          • 2019-07-16
          相关资源
          最近更新 更多