首页 > 解决方案 > 尚未创建导航器时如何从链接导航(与branch.io的深度链接)?

问题描述

我几乎都遵循了 react-navigation 深度链接和 branch.io react-native 文档,并且两者都已被弃用或完全没有帮助。

我想要的是,每当从链接中读取深度链接,导航到某个屏幕时,我不希望在特定屏幕上实现侦听器,我希望它在根路径上,并且要么是 onReady(对于我没有工作)或从导航器容器链接

这是我的代码,非常简单

const linking: LinkingOptions = {
  prefixes: ['agendameio://', 'https://agendame.io', 'https://agendameio.app.link', 'https://agendameio.app-alternative.link'],
  subscribe(listener) {
    const navigation = useNavigation();
    const onReceiveURL = ({ url }: { url: string }) => listener(url);
    Linking.addEventListener('url', onReceiveURL);
    branch.skipCachedEvents();
    branch.subscribe(async ({ error, params, uri }) => {
      if (error) {
        console.error('Error from Branch: ' + error);
        return;
      }
      if (params) {
        DataManager.DynamicURL = params['~id'] === "951933826563912687" ? params.id : undefined;
      }
      let url = params?.['+url'] || params?.['~referring_link']; // params !== undefined ? `agendameio://empresa/${params.id}` : 'agendameio://empresa';
      navigation.navigate(`DetalleEmpresa${params.id}`);
      listener(url);
    });
    return () => {
      Linking.removeEventListener('url', onReceiveURL);
      branch.logout();
    };
  },

由于使用导航,我立即收到错误消息,但我真的不知道还有什么可以用来导航到应用程序内部

编辑:这尤其是错误

错误

编辑 2:我将添加我的导航,以便帮助理解我的问题

function firstStack() {
  return (
    <homeStack.Navigator initialRouteName="EmpresasScreen">
      <homeStack.Screen
        options={({navigation}) => ({
          headerShown: false,
          headerTitle: () => (
            <>
              <View style={styles.viewHeader}>
                <Image 
                  resizeMode="contain" 
                  style={styles.imageLogo} 
                  source={Images.iconoToolbar} 
                />
              </View>
            </>
          ),
        })}
        name="EmpresasScreen"
        component={EmpresasScreen}
      />
      <detalleEmpresaStack.Screen
        options={{ headerShown: false }}
        name="DetalleEmpresaScreen"
        component={DetalleEmpresaScreen}
      />
      <agendamientoStack.Screen
        options={{ headerShown: false }}
        name="AgendamientoScreen"
        component={AgendamientoScreen}
      />
    </homeStack.Navigator>
  );
}

function secondStack() {
  return (
    <misCitasStack.Navigator>
      <misCitasStack.Screen
        options={({navigation}) => ({
          headerShown: false,
          headerTitle: () => (
            <>
              <View style={styles.viewHeader}>
                <Image 
                  resizeMode="contain" 
                  style={styles.imageLogo} 
                  source={Images.iconoToolbar} 
                />
              </View>
            </>
          ),
        })}
        name="MisCitasScreen"
        component={CitasScreen}
      />
      <detalleCitasStack.Screen
        options={({navigation}) => ({
          headerShown: false,
        })}
        name="DetalleCitaScreen"
        component={DetalleCitaScreen}
      />
    </misCitasStack.Navigator>
  );
}

function tabStack() {
  return (
    <tab.Navigator
      screenOptions={({route}) => ({
        tabBarIcon: ({focused}) => {
          let iconName;
          if (route.name === 'Home') {
            iconName = focused
              ? Images.casaActive
              : Images.casa
          } else if (route.name === 'Citas') {
            iconName = focused 
              ? Images.citasActive
              : Images.citas
          }
          return <Image source={iconName} />
        }
      })}
      tabBarOptions={{
        showLabel: false,
      }}>
      <tab.Screen name="Home" component={firstStack} />
      <tab.Screen name="Citas" component={secondStack} />
    </tab.Navigator>
  );
}

function menuStackNavigator() {
  useEffect(() => {
    VersionCheck.needUpdate({forceUpdate: true}).then(async res => {
      if (res.isNeeded) {
        alertNeedUpdate(res.storeUrl, false);
      }
    });
    if(Platform.OS === 'android') {
      NativeModules.SplashScreenModule.hide();
    }
  }, [])
  return (
    <NavigationContainer linking={linking}>
      <stack.Navigator headerMode="none">
        <stack.Screen name="Home" component={tabStack} />
        <stack.Screen name="Error" component={ErrorScreen} />
      </stack.Navigator>
    </NavigationContainer>
  );
};

const styles = StyleSheet.create({
  viewHeader: {
    alignItems: 'center',
    justifyContent: 'center',
  },
  imageLogo: {
    alignItems: 'center',
    justifyContent: 'center',
    marginTop: 6,
    marginBottom: 6
  }
});

export default menuStackNavigator;

标签: javascripttypescriptreact-nativedeep-linkingbranch.io

解决方案


您可以使用配置链接直接打开目标屏幕。

在此处查看更多示例配置链接
此处 URL/feed将打开名为 的屏幕Chat

import { NavigationContainer } from '@react-navigation/native';

const linking = {
  prefixes: ['https://mychat.com', 'mychat://'],
  config: {
    screens: {
      Chat: 'feed/:sort', //URL `/feed` will open screen named `Chat`.
      Profile: 'user',
    }
  },
};

function App() {
  return (
    <NavigationContainer linking={linking} fallback={<Text>Loading...</Text>}>
      <Stack.Navigator>
        <Stack.Screen name="Chat" component={ChatScreen} />
        <Stack.Screen name="Profile" component={ProfileScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}
或使用navigationRef.

阅读有关它的 navigating-without-navigation-prop
等待导航准备好,然后导航。

import { createNavigationContainerRef } from '@react-navigation/native';

function App() {

  const navigationRef = createNavigationContainerRef();

  const navigateWhenNavigationReady = (routeName, params, n = 0) => {
    setTimeout(() => {
        if (navigationRef?.getRootState()) {
            navigationRef.navigate(routeName, params)
        }else if (n < 100) {
            navigateWhenNavigationReady(routeName, params, n + 1);
        }
    }, 300)
  }

  const linking = {
     ...,
     subscribe(listener) {
        ...
        navigateWhenNavigationReady("Chat", {id: 123});
     }
  };


  
  return (
    <NavigationContainer ref={navigationRef} linking={linking}>
      <Stack.Navigator>
        <Stack.Screen name="Chat" component={ChatScreen} />
        <Stack.Screen name="Profile" component={ProfileScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );

}


推荐阅读