Мои настройки похожи на ваши.Я следовал за потоками аутентификации · Реагируйте с навигацией и SplashScreen - Expo Documentation , чтобы настроить мой поток аутентификации, поэтому я был немного разочарован тем, что получить глубокие ссылки через него было сложнотакже.Я смог заставить это работать, настроив навигатор главного переключателя, подход похож на то, что вы заявили, было решение, которое у вас есть на данный момент.Я просто хотел поделиться своим решением для этого, так что есть конкретный пример того, как можно начать работать.Мой навигатор главного переключателя настроен так (также я использую TypeScript, поэтому игнорируйте определения типов, если они незнакомы):
const MainNavigation = createSwitchNavigator(
{
SplashLoading,
Onboarding: OnboardingStackNavigator,
App: AppNavigator,
},
{
initialRouteName: 'SplashLoading',
}
);
const previousGetActionForPathAndParams =
MainNavigation.router.getActionForPathAndParams;
Object.assign(MainNavigation.router, {
getActionForPathAndParams(path: string, params: any) {
const isAuthLink = path.startsWith('auth-link');
if (isAuthLink) {
return NavigationActions.navigate({
routeName: 'SplashLoading',
params: { ...params, path },
});
}
return previousGetActionForPathAndParams(path, params);
},
});
export const AppNavigation = createAppContainer(MainNavigation);
Потребуется любая глубокая ссылка, которую вы хотите направить через поток аутентификации.начать с auth-link
, или с того, что вы решите предварять его.Вот как выглядит SplashLoading
:
export const SplashLoading = (props: NavigationScreenProps) => {
const [isSplashReady, setIsSplashReady] = useState(false);
const _cacheFonts: CacheFontsFn = fonts =>
fonts.map(font => Font.loadAsync(font as any));
const _cacheSplashAssets = () => {
const splashIcon = require(splashIconPath);
return Asset.fromModule(splashIcon).downloadAsync();
};
const _cacheAppAssets = async () => {
SplashScreen.hide();
const fontAssetPromises = _cacheFonts(fontMap);
return Promise.all([...fontAssetPromises]);
};
const _initializeApp = async () => {
// Cache assets
await _cacheAppAssets();
// Check if user is logged in
const sessionId = await SecureStore.getItemAsync(CCSID_KEY);
// Get deep linking params
const params = props.navigation.state.params;
let action: any;
if (params && params.routeName) {
const { routeName, ...routeParams } = params;
action = NavigationActions.navigate({ routeName, params: routeParams });
}
// If not logged in, navigate to Auth flow
if (!sessionId) {
return props.navigation.dispatch(
NavigationActions.navigate({
routeName: 'Onboarding',
action,
})
);
}
// Otherwise, navigate to App flow
return props.navigation.navigate(
NavigationActions.navigate({
routeName: 'App',
action,
})
);
};
if (!isSplashReady) {
return (
<AppLoading
startAsync={_cacheSplashAssets}
onFinish={() => setIsSplashReady(true)}
onError={console.warn}
autoHideSplash={false}
/>
);
}
return (
<View style={{ flex: 1 }}>
<Image source={require(splashIconPath)} onLoad={_initializeApp} />
</View>
);
};
Я создаю глубокую ссылку с параметром запроса routeName
, который является именем экрана, к которому нужно перейти после проверки подлинности (выочевидно, можно добавить любые другие параметры запроса, которые вам нужны).Так как мой SplashLoading
экран обрабатывает загрузку всех шрифтов / ресурсов, а также проверку подлинности, мне нужна каждая глубокая ссылка для маршрутизации через него.Я столкнулся с проблемой, когда я должен был вручную выйти из приложения из многозадачности, нажать на ссылку с глубокой ссылкой и вызвать сбой приложения, потому что глубокая ссылка обошла SplashLoading
, поэтому шрифты не были загружены.
Подход вышеобъявляет переменную action
, которая, если она не установлена, ничего не будет делать.Если параметр запроса routeName
не undefined
, я устанавливаю переменную action
.Это делается так, как только маршрутизатор коммутатора решает, какой путь выбрать на основе аутентификации (Onboarding
или App
), этот маршрут получает дочернее действие и переходит к routeName
после выхода из потока загрузки auth / splash.
Вот пример ссылки, которую я создал, которая отлично работает с этой системой: exp://192.168.1.7:19000/--/auth-link?routeName=ForgotPasswordChange&cacheKey=a9b3ra50-5fc2-4er7-b4e7-0d6c0925c536
Надеемся, что авторы библиотеки сделают эту функцию изначально поддерживаемой, поэтому взломы не нужны.Мне бы тоже хотелось посмотреть, что вы придумали!