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

React自定义侧边栏展开/关闭过渡效果失效求助

React右侧侧边栏过渡效果失效解决方案

我开发了一个从右侧弹出的自定义侧边栏,点击面板外部可关闭,但展开和关闭时的transition(过渡)效果未生效,恳请各位帮忙解决,万分感谢。

相关代码如下:

import React, { useState } from "react";
import ReactDOM from "react-dom";
import SlideDrawer from "./SlideDrawer.jsx";

function App() {
  const [drawerOpen, setDrawerOpen] = useState(false);
  return (
    <div>
      {drawerOpen ? (
        <SlideDrawer show={drawerOpen} {...{ setDrawerOpen }} />
      ) : null}
      <button
        onClick={() => {
          setDrawerOpen(!drawerOpen);
        }}
      >
        Click me!
      </button>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

问题原因

当前代码通过{drawerOpen ? <SlideDrawer ... /> : null}做条件渲染,关闭侧边栏时组件会直接从DOM中卸载,CSS过渡动画没有执行的机会,自然看不到效果。

解决方案

不要卸载组件,始终保持它在DOM中,通过状态控制样式类名来实现显示/隐藏的过渡效果:

1. 修改App组件代码

import React, { useState } from "react";
import ReactDOM from "react-dom";
import SlideDrawer from "./SlideDrawer.jsx";

function App() {
  const [drawerOpen, setDrawerOpen] = useState(false);
  return (
    <div>
      {/* 始终渲染侧边栏组件,通过show状态控制显示 */}
      <SlideDrawer show={drawerOpen} setDrawerOpen={setDrawerOpen} />
      <button
        onClick={() => {
          setDrawerOpen(!drawerOpen);
        }}
      >
        Click me!
      </button>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

2. 编写侧边栏的CSS样式(SlideDrawer.css)

/* 侧边栏容器 */
.slide-drawer {
  position: fixed;
  top: 0;
  right: -300px; /* 默认隐藏在右侧视野外 */
  width: 300px;
  height: 100vh;
  background-color: #fff;
  box-shadow: -2px 0 8px rgba(0, 0, 0, 0.15);
  transition: right 0.3s ease-in-out; /* 添加入场/退场过渡 */
  z-index: 1001;
}

/* 展开状态的样式 */
.slide-drawer.open {
  right: 0; /* 移动到可视区域 */
}

/* 遮罩层 */
.drawer-backdrop {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.4);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.3s ease-in-out, visibility 0.3s ease-in-out;
  z-index: 1000;
}

/* 遮罩层显示状态 */
.drawer-backdrop.open {
  opacity: 1;
  visibility: visible;
}

3. 修改SlideDrawer组件

import React from "react";
import "./SlideDrawer.css";

const SlideDrawer = ({ show, setDrawerOpen }) => {
  // 点击遮罩层关闭侧边栏
  const handleBackdropClick = () => {
    setDrawerOpen(false);
  };

  return (
    <>
      {/* 遮罩层 */}
      <div 
        className={`drawer-backdrop ${show ? 'open' : ''}`} 
        onClick={handleBackdropClick}
      />
      {/* 侧边栏内容 */}
      <div className={`slide-drawer ${show ? 'open' : ''}`}>
        <h3>自定义侧边栏</h3>
        <p>这里是侧边栏内容</p>
        <button onClick={() => setDrawerOpen(false)}>关闭侧边栏</button>
      </div>
    </>
  );
};

export default SlideDrawer;

原理说明

通过始终保持组件在DOM中,利用CSS的transition属性监听right、opacity等属性的变化,切换open类名时,浏览器会自动计算属性变化的过渡动画,从而实现平滑的展开/关闭效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 16:45:30