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

Next.js+Clerk导航栏Bug:已登录时登录注册项短暂闪现

解决Next.js + Clerk导航栏登录选项闪烁问题

问题原因

已登录用户刷新或跳转页面时,Clerk需要时间验证用户会话,初始阶段isSignedIn会返回false或undefined,导致登录、注册选项短暂显示,等认证状态加载完成后才会隐藏,出现视觉闪烁。

解决方案

通过Clerk提供的isLoaded状态判断认证是否完成,在加载完成前不渲染菜单内容(或显示加载占位符),同时优化菜单过滤逻辑,确保状态明确后再渲染对应选项。

修改后的核心代码

'use client'
import { useAuth } from "@clerk/nextjs";
import { useState, useContext, createContext } from 'react';
export const SideBarContext = createContext(true);

const navItems = [
    { icon: 'ICON', label: 'Dashboard', path: '/dashboard' },
    { icon: 'ICON', label: 'Learn', path: '' },
    { icon: 'ICON', label: 'Quiz', path: '/quizzes' },
    { icon: 'ICON', label: 'Sign up', path: '/signup' },
    { icon: 'ICON', label: 'Sign in', path: '/signin' },
    { icon: 'ICON', label: 'Shop', path: '' },
    { icon: 'ICON', label: 'Setting', path: '' },
]

const Menu = () => {
    const expanded = useContext(SideBarContext)
    const { signOut, isSignedIn, isLoaded } = useAuth()

    // 认证未完成时,显示加载占位符或空内容
    if (!isLoaded) {
        return <div className="text-white">加载中...</div>
    }

    // 根据登录状态过滤导航项
    const filteredNavItems = navItems.filter(item => {
        if (isSignedIn) {
            return item.label !== 'Sign up' && item.label !== 'Sign in'
        }
        return true
    })

    const menuItems = filteredNavItems.map(item => (
        <li key={item.label} className='flex gap-2'>
            <span>{item.icon}</span>
            {expanded && <a href={item.path}>{item.label}</a>}
        </li>
    ))

    const logout = () => {
        signOut()
    }

    return (
        <ul className={`text-2xl flex flex-col gap-2  ${expanded ? "items-start" : "items-center"}`}>
            {menuItems}
            {isSignedIn && <li onClick={logout}>Log out</li>}
        </ul>
    )
}

// NavBar组件部分保持不变,此处省略重复代码
export function NavBar() {
    const [expanded, setExpanded] = useState(true);

    const handleClick = () => {
        setExpanded(!expanded)
    }

    const Toggle = () => {
        return (
            <div onClick={handleClick}>
                <label className="btn btn-circle swap swap-rotate" onClick={handleClick}>
                    <input type="checkbox" checked={expanded} onChange={handleClick} />
                    <svg
                        className="swap-off fill-current"
                        xmlns="http://www.w3.org/2000/svg"
                        width="32"
                        height="32"
                        viewBox="0 0 512 512">
                        <path d="M64,384H448V341.33H64Zm0-106.67H448V234.67H64ZM64,128v42.67H448V128Z" />
                    </svg>
                    <svg
                        className="swap-on fill-current"
                        xmlns="http://www.w3.org/2000/svg"
                        width="32"
                        height="32"
                        viewBox="0 0 512 512">
                        <polygon
                            points="400 145.49 366.51 112 256 222.51 145.49 112 112 145.49 222.51 256 112 366.51 145.49 400 256 289.49 366.51 400 400 366.51 289.49 256 400 145.49" />
                    </svg>
                </label>
            </div>
        )
    }

    return (
        <div className={` bg-blue-500 flex items-start min-h-screen transition-all duration-500 ease-in-out ${expanded ? "w-[256px] min-w-[256px]" : "w-[64px] min-w-[64px]"}`}>
            <div className={`bg-blue-500 overflow-x-hidden h-full fixed top-0 transition-all duration-500 ease-in-out ${expanded ? "w-[256px]" : "w-[64px]"}`}>
                <Toggle />
                <div className="text-4xl mb-5">Title</div>
                <div>{expanded ? "true" : "false"}</div>
                <SideBarContext value={expanded}>
                    <Menu />
                </SideBarContext>
            </div>
        </div >
    )
}

关键优化点

  1. 利用isLoaded状态:在Clerk完成认证状态加载前,避免渲染菜单内容,从根源上阻止闪烁。
  2. 过滤导航项逻辑优化:用filter替代原map中条件判断,避免数组出现空元素,渲染更干净。
  3. 退出按钮条件渲染:仅在用户已登录时显示退出按钮,逻辑更严谨。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 14:39:53