React Native认证路由问题:AuthStack仍挂载于RootStack之上求助
问题分析
你的问题核心在于Expo Router的分组路由机制与手动条件渲染Stack组件的冲突。Expo Router的(auth)和(root)分组本身已经是独立的导航栈,直接在Root组件中条件返回RootStack或AuthStack会导致两个栈被同时挂载(前一个栈未被卸载),从而出现AuthStack页面叠加在RootStack之上的情况。
解决方案
我们需要利用Expo Router的路由跳转能力重置导航栈,而非手动渲染不同Stack组件。以下是具体修改步骤:
1. 移除手动定义的RootStack和AuthStack
Expo Router会根据文件目录结构自动生成导航栈,(auth)和(root)分组已作为独立栈存在,无需手动创建Stack组件。
2. 修改Root组件逻辑:用路由跳转替代条件渲染
当认证状态确定后,使用router.replace跳转到对应路由,重置导航栈,避免之前的栈残留。
修改后的完整代码
import { router, Slot, Stack } from "expo-router"; import { StatusBar } from "expo-status-bar"; import { useContext, useEffect, useState } from "react"; import { AuthContext, AuthContextProvider } from "../context/AuthContext"; import { ActivityIndicator, View } from "react-native"; import AsyncStorage from "@react-native-async-storage/async-storage"; import { getUserInforWithToken } from "../controller/AuthController"; function Root() { const { setIsLogin, setToken } = useContext(AuthContext); const [isLoading, setIsLoading] = useState(true); useEffect(() => { const checkAuth = async () => { const token = await AsyncStorage.getItem("token"); if (token) { console.log("token found, user logged in"); setIsLogin(true); setToken(token); // 跳转到root分组首页,重置导航栈 router.replace("/(root)/index"); } else { setIsLogin(false); // 跳转到auth分组登录页,重置导航栈 router.replace("/(auth)/index"); } }; checkAuth().finally(() => { setIsLoading(false); }); }, []); if (isLoading) { console.log("Loading..."); return ( <View className="flex-1 justify-center items-center"> <ActivityIndicator className="p-2 m-2" animating size="large" /> </View> ); } // 用Slot渲染当前路由匹配的页面,由Expo Router自动处理 return <Slot />; } export default function Layout() { return ( <AuthContextProvider> <StatusBar style="light" /> {/* 配置全局Stack默认选项,统一管理头部样式 */} <Stack screenOptions={{ headerShown: false }}> <Stack.Screen name="(auth)" /> <Stack.Screen name="(root)" /> </Stack> <Root /> </AuthContextProvider> ); }
关键改动说明
- 依赖自动路由栈:移除手动Stack组件,让Expo Router根据
(auth)、(root)分组自动生成独立导航栈。 router.replace重置栈:该方法会替换当前导航栈顶部页面并重置整个栈,彻底避免旧栈残留。Slot渲染页面:Expo Router核心组件,负责渲染当前路由匹配的页面,确保路由系统正常工作。- 简化加载逻辑:在
checkAuth的finally中直接设置加载状态结束,无需额外监听isTryingLogin(若该状态无其他用途可从AuthContext中移除)。
额外建议
- 确保文件目录结构符合Expo Router要求:
app/ (auth)/ index.jsx # 登录页 signup.jsx # 注册页 (root)/ index.jsx # 首页 _layout.jsx # 你的Layout组件所在文件 - 保持AuthContext中
isLogin状态同步,避免状态不一致引发路由异常。
内容的提问来源于stack exchange,提问作者dheeraj kumar
相关产品推荐
相关产品推荐

