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
相关产品推荐
相关产品推荐

