Expo托管工作流下React Navigation受保护页面的Deep Link触发问题求助
兄弟我太懂你这种头疼的情况了!冷启动时Deep Link直接失效,大概率就是你猜的那样——路由还没准备好,认证逻辑还在异步跑着,ProtectedScreens还没挂载,React Navigation找不到对应的页面路径,自然就跳不动了。我之前做Expo项目时也踩过这个坑,给你分享几个亲测有效的解决思路:
第一步:先把Deep Link存起来,别着急导航
冷启动时先捕获到Deep Link的URL,把它存在状态里,等认证完成、ProtectedScreens渲染后再处理导航:
import { Linking } from 'expo'; import { useState, useEffect } from 'react'; import { NavigationContainer, useNavigationContainerRef } from '@react-navigation/native'; export default function App() { const navigationRef = useNavigationContainerRef(); const [initialDeepLink, setInitialDeepLink] = useState(null); const [isAuth, setIsAuth] = useState(false); // 冷启动时获取初始Deep Link useEffect(() => { async function getInitialLink() { const url = await Linking.getInitialURL(); if (url) setInitialDeepLink(url); } getInitialLink(); }, []); // 检查登录状态(这里替换成你的真实认证逻辑) useEffect(() => { async function checkAuthStatus() { const authToken = await AsyncStorage.getItem('userToken'); setIsAuth(!!authToken); } checkAuthStatus(); }, []); // 登录完成后,再处理存好的Deep Link useEffect(() => { if (isAuth && initialDeepLink) { // 解析Deep Link的路径 const { pathname } = Linking.parse(initialDeepLink); // 用导航实例跳转 navigationRef.current.navigate(pathname); // 清空状态,避免重复跳转 setInitialDeepLink(null); } }, [isAuth, initialDeepLink]); return ( <NavigationContainer ref={navigationRef} linking={yourLinkingConfig}> {!isAuth ? <LogIn /> : <ProtectedScreens />} </NavigationContainer> ); }
第二步:统一处理后台唤醒的Deep Link
除了冷启动,还要考虑App在后台时被Deep Link唤醒的情况,这时候可以监听Linking的url事件,同样根据登录状态决定是直接跳转还是先存起来:
useEffect(() => { const handleDeepLink = ({ url }) => { if (isAuth) { // 已登录直接跳转 const { pathname } = Linking.parse(url); navigationRef.current.navigate(pathname); } else { // 未登录先存起来,等登录后处理 setInitialDeepLink(url); } }; const linkSubscription = Linking.addEventListener('url', handleDeepLink); return () => linkSubscription.remove(); }, [isAuth]);
几个关键注意点
- 确保你的
linking配置里的路径和ProtectedScreens内的路由完全匹配,比如嵌套导航的路径要写对,比如/profile/:userId这种动态参数也要对应好; - 测试时尽量用EAS Build打包后的安装包测,Expo Go的Deep Link行为可能和正式环境有差异;
- 认证逻辑要避免竞态条件,比如别同时发起多个异步请求修改
isAuth状态,不然可能导致Deep Link处理时机出错。
我当时这么调整后,冷启动的Deep Link就完全正常了,你可以试试这个方案!
备注:内容来源于stack exchange,提问作者SKeney
相关产品推荐
相关产品推荐

