点击菜单关闭按钮后state未置为false,NavBar关闭动画失效
问题根源
核心问题是条件渲染导致组件直接被卸载:不管是Header还是Home组件里,你都用了{asideBar && <NavBar />}的写法——当点击关闭按钮把asideBar设为false时,NavBar会立刻从DOM中消失,关闭动画还没来得及跑完就没了,自然看不到动画效果。
另外,你的动画逻辑完全依赖组件存在于DOM中,组件一被移除,动画就无法执行。
修复方案
方案1:始终保留NavBar组件,用state控制显示/隐藏(最简单)
把条件渲染改成始终渲染NavBar,通过传入的state控制类名触发动画,组件不会被卸载,动画能完整执行。
修改Header组件的渲染逻辑:
export function Header() { const [asideBar, setAsideBar] = useState(false) return ( <header className="fixed top-0 left-0 right-0 w-screen h-20 p-7 z-20 bg-black overflow-hidden" > <nav className="flex flex-row justify-between items-center text-customGray pr-4"> <div> <button onClick={() => setAsideBar(true)} className="mr-4"> {/* <MenuIcon /> */} </button> {/* 删掉条件判断,直接渲染NavBar */} <NavBar state={asideBar} setStateFunction={setAsideBar} /> <button> {/* <SearchIcon /> */} </button> </div> <span className="ms-madi-regular tracking-wider text-2xl -rotate-12">WebWish</span> <div> <button className="mr-3"> <a href="/auth/login"> {/* <LoginIcon /> */} </a> </button> <button> {/* <ShopIcon /> */} </button> </div> </nav> </header> ) }
同样修改Home组件:
export default function Home() { const [asideBar, setAsideBar] = useState(false); return ( <main className={`flex min-h-screen flex-col items-center justify-between p-24 ${inter.className}`} > <button onClick={() => setAsideBar(true)} className="mr-4"> Open the sidebar </button> <button onClick={() => setAsideBar(false)} className="mr-4"> close sidebar </button> {/* 直接渲染NavBar,不用条件判断 */} <NavBar state={asideBar} setStateFunction={setAsideBar} /> </main> ); }
方案2:监听动画结束事件,完成后再卸载组件(适合需彻底移除组件的场景)
如果不想让NavBar一直留在DOM里,可以监听动画结束事件,等关闭动画跑完后再更新state卸载组件:
修改NavBar组件:
import CloseButton from "./CloseButton" import { useEffect, useState, useRef } from "react" export const NavBar = ({ state, setStateFunction }: { state: boolean, setStateFunction: (value: boolean) => void }) => { const navRef = useRef<HTMLDivElement>(null); // 用本地state控制组件显示,避免父组件直接卸载 const [isVisible, setIsVisible] = useState(state); useEffect(() => { if (state) { // 打开时直接显示 setIsVisible(true); } else { // 关闭时先触发动画,结束后再隐藏 const handleAnimationEnd = () => { setIsVisible(false); setStateFunction(false); }; const element = navRef.current; if (element) { element.addEventListener('animationend', handleAnimationEnd); return () => element.removeEventListener('animationend', handleAnimationEnd); } } }, [state, setStateFunction]); if (!isVisible) return null; return ( <div ref={navRef} className={`w-[370px] bg-black fixed top-0 left-0 z-40 h-screen transform transition-transform duration-1000 ${state === false ? 'animate-translateX0' : 'animate-translateX'}`} > <button className="absolute top-5 right-5 font-bold text-2xl" onClick={() => setStateFunction(false)}> <CloseButton /> </button> <div className="ml-6 mt-20"> <nav className=""> <ul className=""> <li className="mb-5 hover:translate-x-3 tracking-wider"><a className="hover:text-gray-200 hover:translate-x-3 transition transform" href="">HOME</a></li> <li className="mb-5 tracking-wider"><a href="">CLOTHES</a></li> <li className="mb-5 tracking-wider"><a href="">ELECTRONICS</a></li> <li className="mb-5 tracking-wider"><a href="">FURNITURE</a></li> <li className="mb-5 tracking-wider"><a href="">SHOES</a></li> <li className="mb-5 tracking-wider"><a href="">MISCELLANEOUS</a></li> <li className="mb-5 tracking-wider"><a href="">OFFERS</a></li> <li className="tracking-wider"><a href="">SALE</a></li> </ul> </nav> </div> <span className="ms-madi-regular tracking-wider text-2xl -rotate-12 absolute bottom-24 left-32">WebWish</span> </div> ) }
必做检查:确认动画CSS定义正确
确保animate-translateX和animate-translateX0的动画逻辑是反向的,示例:
@keyframes slideIn { from { transform: translateX(-100%); } to { transform: translateX(0); } } @keyframes slideOut { from { transform: translateX(0); } to { transform: translateX(-100%); } } .animate-translateX { animation: slideIn 1s forwards; } .animate-translateX0 { animation: slideOut 1s forwards; }
额外提醒
你现在在Header和Home组件里各定义了一套asideBar状态,会导致两个组件的侧边栏状态不统一。如果是全局侧边栏,建议用React Context或状态管理库(如Zustand、Redux)统一管理状态,避免出现状态混乱。
内容的提问来源于stack exchange,提问作者ezequiel correa
相关产品推荐
相关产品推荐

