Next.js中Supabase认证重定向闪烁问题(HOC+useSessionContext)
问题原因
- useEffect执行时机延迟:
useEffect是在组件挂载并完成DOM渲染后才触发的。当isLoading变为false且session存在时,组件已经先渲染了登录页内容,之后才执行useEffect里的重定向逻辑,导致用户看到短暂的登录页/闪烁。 - 渲染逻辑顺序问题:原代码中,
isLoading结束后直接返回登录页组件,仅在useEffect中判断session进行重定向,这就导致登录页会先被渲染到DOM,再触发跳转。
解决方案
调整HOC的渲染逻辑,在渲染阶段就判断session状态,避免登录页被渲染;同时保留useEffect完成最终重定向。具体修改如下:
import CircularProgress from '@mui/material/CircularProgress'; import { useSessionContext } from '@supabase/auth-helpers-react'; import { useRouter } from 'next/router'; import { FC, useEffect } from 'react'; import ErrorIcon from '@mui/icons-material/Error'; import { Typography } from '@mui/material'; export const withAuth = <T extends Record<string, unknown>>(Component: FC<T>, redirectLink = '/') => { const AuthenticatedComponent: FC<T> = (props) => { const router = useRouter(); const { isLoading, session, error } = useSessionContext(); useEffect(() => { // 仅在加载完成且session存在时执行重定向 if (!isLoading && session) { router.replace(redirectLink); } }, [isLoading, session, router]); // 加载中显示进度条 if (isLoading) return <CircularProgress color='primary' size={'2rem'} />; // 已登录但未完成重定向时,继续显示加载状态(避免渲染登录页) if (session) return <CircularProgress color='primary' size={'2rem'} />; // 认证错误提示 if (error) return ( <> <ErrorIcon color='error' fontSize='large' /> <Typography variant='body1'>We are experiencing technical difficulties. Please try again later.</Typography> </> ); // 未登录时才渲染目标组件(登录页) return <Component {...(props as T)} />; }; return AuthenticatedComponent; };
关键修改点
- 在
isLoading结束后,优先判断session是否存在:如果存在,直接返回加载组件而非登录页,避免DOM中出现登录页内容。 - 调整
useEffect的依赖项,确保加载完成后立即检查session并触发重定向。
这样修改后,已登录用户访问登录页时,只会看到加载进度条,直到重定向完成,不会出现登录页的短暂显示或闪烁问题。
内容的提问来源于stack exchange,提问作者Mnai
相关产品推荐
相关产品推荐

