Expo SDK49+TypeScript开发RN应用遇AbortError: Aborted问题求助
解决Expo Router中AuthProvider导航触发的AbortError问题
问题原因
你遇到的AbortError: Aborted是因为重复触发导航请求导致的:当user状态变更时,useEffect执行导航操作,而导航会改变当前路由的rootSegment,进而再次触发useEffect,导致多次调用router.replace。Expo Router会中止之前未完成的导航请求,最终抛出该错误。
解决方案
通过优化导航判断逻辑,避免不必要的重复导航,具体修改如下:
- 统一用户状态类型
将user的状态类型改为string | null,用null表示未登录/未初始化状态,空字符串容易和有效用户名混淆:
const [user, setUser] = useState<string | null>(null);
- 优化导航判断逻辑
使用usePathname获取当前完整路径,仅当目标路径与当前路径不一致时才执行导航,同时移除rootSegment的依赖,避免循环触发:
import { usePathname, useRouter } from 'expo-router'; export function AuthProvider({ children }: React.PropsWithChildren) { const router = useRouter(); const currentPath = usePathname(); const [user, setUser] = useState<string | null>(null); useEffect(() => { // 初始加载状态(比如还在从本地存储读取用户信息),不执行导航 if (user === null) return; // 确定目标路径 const targetPath = user ? "/" : "/(auth)/Onboarding"; // 仅当当前路径与目标路径不同时才导航 if (currentPath !== targetPath) { router.replace(targetPath); } }, [user, currentPath, router]); return ( <AuthContext.Provider value={{ signIn: () => { setUser("Hatem"); }, signOut: () => { setUser(null); }, }}> {children} </AuthContext.Provider> ); }
- 同步signOut的状态设置
将signOut中的setUser("")改为setUser(null),保持状态判断的一致性。
额外注意事项
- 确保路由组配置正确:确认
/(app)/_layout.tsx是根路径/的所属组,/(auth)/_layout.tsx包含Onboarding页面 - 如果有异步加载用户状态的逻辑(比如从AsyncStorage读取),建议在加载完成前保持
user为null,并显示加载界面,避免过早触发导航 - 避免在短时间内多次调用
setUser,这也可能导致重复导航触发错误
内容的提问来源于stack exchange,提问作者CodeNKoffee
相关产品推荐
相关产品推荐

