You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何等待Expo Router就绪后再执行路由操作?

解决Expo Router v2中“导航在根布局挂载前执行”的错误

你遇到的错误是因为在index.js的组件渲染阶段直接调用router.replace,此时根布局的导航器还未完成挂载,导致路由操作无法正常执行。以下是两种有效解决方案:

方案一:在index.js中使用useEffect延迟导航

将路由跳转逻辑放到useEffect钩子中,确保组件挂载后(此时导航器已就绪)再执行导航操作:

修改后的index.js代码:

import { Text, View, useEffect } from 'react-native';
import { Link, router} from 'expo-router';

export default function App(){
    const isLoggedIn = false; // 替换为实际登录状态判断逻辑

    useEffect(() => {
        // 组件挂载后执行导航
        isLoggedIn ? router.replace("/home") : router.replace("/welcome");
    }, [isLoggedIn]);

    return (
        <View>
            <Text>Sorry, an error has occured, this page should not be visible</Text>
            <Text>Current file: index.js</Text>
            <Link href="/home">Go to default page</Link>
        </View>
    )
}

方案二:在RootLayout中处理重定向(推荐)

把路由重定向逻辑移到根布局_layout.js中,更符合Expo Router的架构设计,避免中间页index.js的冗余:

修改后的_layout.js代码:

import { useFonts } from 'expo-font';
import { SplashScreen, Stack, useRouter } from 'expo-router';
import { useEffect } from 'react';
import { useColorScheme } from 'react-native';

export {
  ErrorBoundary,
} from 'expo-router';

export const unstable_settings = {
  initialRouteName: 'index',
};

SplashScreen.preventAutoHideAsync();

export default function RootLayout() {
  const colorScheme = useColorScheme();
  const router = useRouter();
  // 替换为实际的登录状态获取逻辑,比如从AsyncStorage/Context读取
  const isLoggedIn = false;

  const [loaded, error] = useFonts({
  });

  useEffect(() => {
    if (error) throw error;
  }, [error]);

  useEffect(() => {
    if (loaded) {
      SplashScreen.hideAsync();
      // 字体加载完成后执行导航
      isLoggedIn ? router.replace("/home") : router.replace("/welcome");
    }
  }, [loaded, isLoggedIn]);

  if (!loaded) {
    return null;
  }
  
  return (
    <Stack screenOptions={{ headerShown: false }}>
      <Stack.Screen name="home" options={{}} />
      <Stack.Screen name="welcome" options={{}} />
    </Stack>
);
}

额外说明

  • 如果登录状态是异步获取的(比如从AsyncStorage读取),需要在useEffect中用async/await处理,确保获取到状态后再执行导航:
    useEffect(() => {
      async function checkAuth() {
        const storedLoginStatus = await AsyncStorage.getItem('isLoggedIn');
        const isLoggedIn = storedLoginStatus === 'true';
        isLoggedIn ? router.replace("/home") : router.replace("/welcome");
      }
      if (loaded) {
        SplashScreen.hideAsync();
        checkAuth();
      }
    }, [loaded]);
    
  • 使用方案二时可以直接删除index.js文件,因为根布局会直接处理重定向逻辑。

内容的提问来源于stack exchange,提问作者10xNerd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 03:20:59