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

Expo Router应用启动时如何根据用户角色重定向至对应目录

问题解决:Expo路由启动时根据用户角色定向到对应目录

问题根源

Expo Router启动时,若未明确控制初始路由,会默认加载同层级下字母排序靠前的路由目录(如business_auth)。当前配置仅在未登录时重定向到登录页,但已登录用户启动应用时,会话状态读取滞后于路由初始化,导致先加载了字母排序靠前的目录。

解决方案

通过在auth/_layout.tsx中添加基于角色的路由重定向逻辑,结合会话加载状态控制,避免启动时的错误跳转。核心是在会话状态就绪后,根据用户角色定向到对应目录,同时阻止初始路由的默认渲染。

修改后的auth/_layout.tsx代码

import * as SplashScreen from "expo-splash-screen";
import { SessionProvider, useSession } from "@/services/ctx";
import { ErrorBoundary, Slot, useRouter } from "expo-router";
import { useEffect, useState } from "react";

export { ErrorBoundary } from "expo-router";

export const unstable_settings = {
  initialRouteName: "login",
};

// 保持启动页直到重定向完成
SplashScreen.preventAutoHideAsync();

export default function RootLayout() {
  return (
    <SessionProvider>
      {/* 新增重定向处理组件,在SessionProvider内部可读取会话状态 */}
      <RoleBasedRedirect />
      <Slot />
    </SessionProvider>
  );
}

function RoleBasedRedirect() {
  const router = useRouter();
  const { session, isLoading } = useSession(); // 假设useSession返回:会话信息(含role)、加载状态
  const [redirectDone, setRedirectDone] = useState(false);

  useEffect(() => {
    const handleRedirect = async () => {
      if (!isLoading) {
        if (session) {
          // 根据角色匹配目标路由
          const targetRoute = session.role === "staff" 
            ? "/auth/staff_auth" 
            : "/auth/business_auth";
          
          // 避免重复重定向循环
          const currentRoute = router.getCurrentRoute()?.name;
          if (currentRoute !== targetRoute.split("/").pop()) {
            router.replace(targetRoute);
          }
        } else {
          // 未登录时跳转登录页
          router.replace("/auth/login");
        }
        // 重定向完成后隐藏启动页
        await SplashScreen.hideAsync();
        setRedirectDone(true);
      }
    };

    handleRedirect();
  }, [session, isLoading, router]);

  // 重定向完成前不渲染任何内容,防止闪现错误页面
  if (!redirectDone) {
    return null;
  }

  return null;
}

关键注意事项

  1. 会话状态需包含加载状态:确保SessionProvider在从本地存储(如AsyncStorage)读取会话时,返回isLoading状态,避免在会话未就绪时执行重定向。
  2. 使用router.replace:替代push,避免留下历史记录,确保用户无法通过返回按钮回到登录页(除非主动退出)。
  3. 阻止初始路由渲染:重定向完成前返回null,避免启动时闪现business_auth页面。
  4. 启动页控制:保持SplashScreen直到重定向完成,提升用户体验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 10:44:59