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

React Native/Expo应用登出后未自动跳转至认证页面问题

Expo Router 登出后无法自动跳转到认证页面的解决方案

你的核心问题是:RootLayout仅在初始加载时根据user状态渲染不同路由栈,但user状态变化(比如登出设为null)时,Expo Router的路由状态未同步更新,导致已加载的(tabs)页面仍可访问。

修复方案

1. 修改RootLayout,监听user状态自动跳转路由

更新Root.tsx,添加对user状态的监听,通过router.replace强制切换路由栈,实现统一的认证跳转逻辑:

import { router, Stack } from 'expo-router';
import { StatusBar } from 'expo-status-bar';
import React, { useContext, useEffect, useState } from 'react';
import 'react-native-reanimated';
import "./global.css";
import { View, Text } from 'react-native';
import { AuthContext } from '@/context/AuthProvider'

export default function RootLayout() {
    const [isLoading, setisLoading] = useState(true)
    const { user } = useContext(AuthContext)

    useEffect(() => {
        setTimeout(() => {
            setisLoading(false)
        }, 2000)
    }, [])

    // 监听user状态变化,自动切换路由
    useEffect(() => {
        if (!isLoading) {
            user ? router.replace('/(tabs)') : router.replace('/(auth)')
        }
    }, [user, isLoading])

    if(isLoading) {
        return (
            <View>
                <Text>Loading...</Text>
            </View>
        )
    }

    // 统一渲染所有路由配置,跳转逻辑由useEffect处理
    return (
        <View className="h-full">
            <Stack screenOptions={{ headerShown: false }}>
                <Stack.Screen name="(tabs)" />
                <Stack.Screen name="(auth)" />
                <Stack.Screen name="+not-found" />
            </Stack>
            <StatusBar style="auto" />
        </View>
    );
}

2. 优化AuthProvider的状态更新(可选)

你当前login/logout中的console.log(user)会打印旧值,因为setUser是异步操作,若需要在状态更新后执行逻辑,可改用回调形式:

import React, { createContext, useState } from "react";

export const AuthContext = createContext();

export const AuthProvider = ({children}) => {
    const [user, setUser] = useState(null)

    return ( 
        <AuthContext.Provider 
            value = {{
                user,
                setUser,
                login: (email, password) => {
                    console.log('login')
                    setUser(() => {
                        const newUser = 'Thomas';
                        console.log(newUser);
                        return newUser;
                    })
                },
                logout: () => {
                    console.log('logout')
                    setUser(null)
                }
            }}
        >
            {children}
        </AuthContext.Provider> 
    )
}

原理说明

Expo Router的Stack组件仅用于定义路由规则,而非触发跳转。初始加载时的条件渲染只是加载了对应路由配置,但不会重置已激活的路由栈。通过监听user状态并调用router.replace,可以强制替换当前路由栈,实现登录/登出时的自动跳转,无需在logout函数中手动处理跳转逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 05:54:53