用户已登录状态下页面仍闪现splash启动页如何修复
问题根因
闪现的核心原因是当前鉴权逻辑没有区分「正在校验用户登录状态」和「校验完成、用户确实未登录」两种场景。初始状态下user被设为null,页面首次渲染时会直接判定为未登录展示splash页,等异步的checkUser请求完成拿到登录用户信息后才会切换到dashboard,就出现了闪现问题。
解决方法
步骤1:给AuthContext添加加载状态
在鉴权上下文里新增isLoading字段,标记当前是否正在校验用户状态,校验完成后再更新状态,修改后的代码如下:
const UserContext = createContext({}); export default function AuthContext({ children }) { const router = useRouter(); const [user, setUser] = useState(null); // 新增加载状态,初始为true表示正在校验登录态 const [isLoading, setIsLoading] = useState(true); useEffect(() => { checkUser(); }, []); useEffect(() => { Hub.listen("auth", () => { checkUser(); }); }, []); const checkUser = async () => { setIsLoading(true); // 每次重新校验用户时开启加载状态 try { // 保留原有获取用户的代码,拿到用户后调用setUser赋值 const currentUser = await getCurrentUser(); // 替换为你实际获取用户的接口逻辑 setUser(currentUser); } catch (err) { console.log("error with AuthContext", err); setUser(null); } finally { // 无论校验成功失败,都关闭加载状态 setIsLoading(false); } }; return ( // 把isLoading传入上下文供组件调用 <UserContext.Provider value={{ user, setUser, isLoading }}> {children} </UserContext.Provider> ); } export const useUser = () => useContext(UserContext);
步骤2:修改Home组件的渲染逻辑
优先判断加载状态,加载阶段展示和splash样式统一的占位内容,避免提前渲染splash或者dashboard,修改后的代码如下:
const Home = () => { const { user, isLoading } = useUser(); const MainComponent = () => { return ( <> <SidebarNav /> <main className="flex-1 bg-gray-100"> code goes here </main> </> ); }; // 加载状态渲染逻辑,可根据需求调整为骨架屏、加载动画,样式和splash保持一致体验更流畅 if (isLoading) { return <div className="h-screen w-full bg-white flex items-center justify-center">加载中...</div> } return ( <> <Head> <title>Create Next App</title> <meta name="description" content="Generated by create next app" /> <link rel="icon" href="/favicon.ico" /> </Head> {user ? ( <div>{MainComponent()}</div> ) : ( <SplashPage /> )} </> ); }; export default Home;
可选优化(Next.js场景)
如果你的项目是Next.js,还可以配合服务端能力进一步优化体验:
- 采用
getServerSideProps在服务端提前完成鉴权,直接返回对应页面内容,客户端完全不会出现切换闪现 - 用Next.js中间件在请求到达页面前完成鉴权跳转,避免客户端渲染阶段的状态切换
内容的提问来源于stack exchange,提问作者hellomello
相关产品推荐
相关产品推荐

