使用Expo Router根布局useEffect跳转报错:未挂载根布局
解决Expo Router根布局鉴权重定向报错问题
错误原因
Expo Router要求根布局组件首次渲染必须渲染<Slot />或其他导航器,以此初始化整个导航系统。如果在根布局未完成挂载(比如useEffect同步执行阶段)就调用导航方法,就会触发Attempted to navigate before mounting the Root Layout component错误。
解决方案
1. 确保根布局优先渲染<Slot />
根布局不能在初始渲染时跳过<Slot />,必须先渲染它完成导航系统初始化,再在后续副作用中处理鉴权跳转。
2. 修改后的代码示例
// app/_layout.tsx import { useEffect } from 'react'; import { Slot, useRouter } from 'expo-router'; import { useAuth } from '../hooks/useAuth'; // 假设这是你的鉴权自定义Hook export default function RootLayout() { const { isAuth } = useAuth(); const router = useRouter(); useEffect(() => { // 组件挂载完成后再判断是否跳转 if (!isAuth) { router.replace("/(auth)/sign-in"); } }, [isAuth, router]); // 首次渲染必须返回Slot,不能通过条件判断省略 return <Slot />; }
3. 进阶:添加加载状态优化体验
如果isAuth是异步获取的(比如从本地存储或API请求),可以先显示加载状态,避免短暂暴露未授权页面:
// app/_layout.tsx import { useEffect, useState } from 'react'; import { Slot, useRouter } from 'expo-router'; import { useAuth } from '../hooks/useAuth'; export default function RootLayout() { const { isAuth, loading } = useAuth(); // 假设Hook返回加载状态 const router = useRouter(); useEffect(() => { if (!loading && !isAuth) { router.replace("/(auth)/sign-in"); } }, [isAuth, loading, router]); // 加载中显示占位,但仍需保证Slot渲染 if (loading) { return ( <div style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}> <p>加载中...</p> <Slot /> </div> ); } return <Slot />; }
关键注意点
- 根布局的首次渲染输出必须包含
<Slot />,不能用条件判断(比如if (!isAuth) return null)跳过它。 - 导航操作必须在组件挂载完成后执行(
useEffect的回调会在挂载后触发),避免在初始渲染阶段调用导航方法。
内容的提问来源于stack exchange,提问作者Avishka Vishmitha
相关产品推荐
相关产品推荐

