如何用expo-router v2与Supabase在Index.tsx校验登录状态并跳转至登录页
实现Supabase + Expo Router v2的登录校验与重定向
步骤1:初始化Supabase客户端
先创建supabase.ts文件,完成Supabase客户端初始化(替换为你的项目配置信息):
import { createClient } from '@supabase/supabase-js'; import { Constants } from 'expo-constants'; const supabaseUrl = Constants.expoConfig?.extra?.supabaseUrl || ''; const supabaseAnonKey = Constants.expoConfig?.extra?.supabaseAnonKey || ''; export const supabase = createClient(supabaseUrl, supabaseAnonKey);
步骤2:在Index.tsx中实现登录校验逻辑
在Index.tsx里异步检查用户状态,处理加载状态,未登录时自动重定向到登录页:
import { useEffect, useState } from 'react'; import { supabase } from '../path/to/supabase'; // 替换为你的supabase文件路径 import { redirect } from 'expo-router'; import { View, ActivityIndicator, Text } from 'react-native'; export default function Index() { const [isLoading, setIsLoading] = useState(true); useEffect(() => { // 检查当前登录用户 const checkUser = async () => { const { data: { user } } = await supabase.auth.getUser(); if (!user) { redirect('/login'); } setIsLoading(false); }; checkUser(); // 监听用户状态变化,处理登出后自动跳转 const subscription = supabase.auth.onAuthStateChange((_event, session) => { if (!session) { redirect('/login'); } }); return () => subscription.unsubscribe(); }, []); // 加载状态显示指示器,避免页面闪屏 if (isLoading) { return ( <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}> <ActivityIndicator size="large" /> </View> ); } // 已登录状态渲染页面内容 return ( <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}> <Text>已登录,欢迎访问Index页面!</Text> {/* 你的其他页面功能代码 */} </View> ); }
步骤3:可选优化 - 封装登录校验Hook
为了复用校验逻辑,可封装自定义Hook useAuthStatus.ts:
import { useState, useEffect } from 'react'; import { supabase } from '../path/to/supabase'; import { redirect } from 'expo-router'; export const useAuthStatus = () => { const [isLoading, setIsLoading] = useState(true); const [isAuthenticated, setIsAuthenticated] = useState(false); useEffect(() => { const checkAuth = async () => { const { data: { user } } = await supabase.auth.getUser(); setIsAuthenticated(!!user); setIsLoading(false); if (!user) { redirect('/login'); } }; checkAuth(); const subscription = supabase.auth.onAuthStateChange((_event, session) => { setIsAuthenticated(!!session); if (!session) { redirect('/login'); } }); return () => subscription.unsubscribe(); }, []); return { isLoading, isAuthenticated }; };
在Index.tsx中使用该Hook:
import { useAuthStatus } from '../path/to/useAuthStatus'; import { View, ActivityIndicator, Text } from 'react-native'; export default function Index() { const { isLoading } = useAuthStatus(); if (isLoading) { return ( <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}> <ActivityIndicator size="large" /> </View> ); } return ( <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}> <Text>已登录,欢迎访问Index页面!</Text> {/* 你的其他页面功能代码 */} </View> ); }
注意事项
- 确保
supabase.ts中的supabaseUrl和supabaseAnonKey配置正确,可在Expo的app.json的extra字段中设置。 - Expo Router的
redirect是客户端跳转,适配当前Tab路由结构。 - 监听
onAuthStateChange可处理用户在Index页面主动登出的场景,自动触发跳转。
内容的提问来源于stack exchange,提问作者ambroiselebs
相关产品推荐
相关产品推荐

