如何根据用户登录状态条件渲染antd Menu菜单项
Antd 水平菜单根据登录态动态隐藏注册项实现方案
核心实现思路
不要写死静态菜单项数组,根据响应式的user登录态动态拼接菜单项配置,同时修复原有代码硬编码像素边距的适配问题。
最简实现(适配你现有代码结构)
直接通过条件展开语法控制Register项是否注入菜单项数组,删掉原来硬编码的1030px左边距,仅给最右侧的认证相关菜单加marginLeft: auto即可自动实现右对齐,适配所有屏幕宽度:
// 从你的状态管理/上下文/路由中获取响应式user值 // const user = useSelector(state => state.user) // const user = useContext(AuthContext) const items = [ // 这里放你常驻的左侧菜单项,比如首页、文档等 // 未登录时才注入注册菜单项 ...(!user ? [{ label: <Link to='/register'>Register</Link>, key: 'register', icon: <UserAddOutlined />, }] : []), { label: <Link to='/login'>Login</Link>, key: 'login', icon: <UserOutlined />, // 仅靠这一句就能把当前项及之后的所有菜单推到最右侧,不需要写死像素值 style: { marginLeft: 'auto'}, }, ]; return <Menu mode="horizontal" items={items} />;
扩展优化版本(登录后替换登录项为退出)
如果需要登录后把登录按钮替换为退出登录按钮,可以参考下面的写法:
const navigate = useNavigate(); const handleLogout = () => { // 在这里写清除登录态、token的逻辑 localStorage.removeItem('token'); navigate('/login'); }; const items = [ // 常驻左侧菜单 { label: <Link to='/'>首页</Link>, key: 'home' }, // 未登录才显示注册 ...(!user ? [{ label: <Link to='/register'>Register</Link>, key: 'register', icon: <UserAddOutlined />, }] : []), // 登录态显示退出,未登录显示登录,始终靠右 { label: user ? <span onClick={handleLogout}>退出登录</span> : <Link to='/login'>Login</Link>, key: user ? 'logout' : 'login', icon: user ? <LogoutOutlined /> : <UserOutlined />, style: { marginLeft: 'auto' }, } ]; return <Menu mode="horizontal" items={items} />;
注意事项
- 不要用给注册项加
display: none的方式隐藏,这种方案会保留DOM节点,容易触发antd Menu的选中态、key匹配异常 - 必须保证
user是响应式状态,登录/退出操作触发user值更新时,菜单会自动重渲染,不需要额外做强制刷新 - 删掉原有硬编码的
marginLeft: 1030,这种写死像素的写法在不同屏幕分辨率、不同菜单长度下会出现严重的错位问题,marginLeft: auto是水平flex布局下右对齐的标准写法,适配性更好
内容的提问来源于stack exchange,提问作者kaiyu wei
相关产品推荐
相关产品推荐

