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

React中条件渲染组件实现滑入淡入动画:侧边栏动画失效如何解决

你当前动画不生效的核心原因是使用了open &&的条件渲染逻辑,当open为false时,侧边栏和遮罩层会直接从DOM树中卸载,过渡动画还没触发执行组件就已经消失,自然看不到效果。

不需要完全调整布局结构,只需要修改少量渲染逻辑和样式即可实现动画,优化方案如下:

  • 移除侧边栏、遮罩层外层的条件渲染判断,让两个组件始终保留在DOM中,通过样式控制显隐和动画效果
  • 侧边栏关闭状态下新增invisible类,避免侧边栏滑出视口后依然会误触发点击事件,桌面端布局下可以通过md断点重置位移样式保证正常显示
  • 遮罩层新增透明度过渡,关闭状态下设置opacity-0 pointer-events-none,避免隐藏状态下拦截页面点击

修改后的完整代码参考:

export default function Layout(props) {
  const [open, setOpen] = useState(false);
  const isMobile = useMediaQuery({ query: "(max-width: 768px)" });

  return (
    <div className="relative h-screen w-screen flex">
      
      {/* SIDEBAR */}
      <section className={`fixed top-0 left-0 bg-white h-screen z-20 w-64 md:relative md:w-1/3 md:translate-x-0 delay-400 duration-500 ease-in-out transition-all transform ${open ? "translate-x-0 visible" : "translate-x-full invisible"}`}></section>

      {/* 遮罩层 */}
      {isMobile && (
        <div
          onClick={() => setOpen(false)}
          className={`fixed left-0 top-0 bg-black bg-opacity-60 w-screen h-screen z-10 transition-opacity duration-300 ease-in-out ${open ? "opacity-100" : "opacity-0 pointer-events-none"}`}
        ></div>
      )}

      <div className="relative w-full h-full">
        {/* TOP BAR */}
        <div className="absolute top-0 h-16 w-full bg-blue-600 flex flex-row items-center p-2 z-5">
          <MenuIcon
            onClick={() => setOpen(!open)}
            className="text-white"
            width={30}
            height={30}
          />
        </div>

        {/* CONTENT */}
        <div className="pt-16 h-full w-full overflow-y-auto">{props.children}</div>
      </div>
    </div>
  );
}

如果确实需要在侧边栏关闭时卸载组件节省性能,可以额外加一个状态控制卸载延迟,在setOpen(false)后等动画执行完成(比如设置600ms的延迟,比动画总时长多100ms即可)再把组件从DOM中移除即可,不需要调整整体布局结构。

内容的提问来源于stack exchange,提问作者Nikola-Milovic

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 09:45:05