如何使用ReactJS实现流畅的SlideToggle滑动切换效果
用React实现流畅的SlideToggle效果
核心思路
直接通过React状态切换元素display属性(比如none/block)会缺失过渡动画,导致效果生硬。正确做法是利用CSS的max-height过渡属性,结合React状态切换类名/内联样式,模拟出类似jQuery的流畅滑动展开/收起效果。
实现方案
1. 基础版组件(固定最大高度)
这种方式适合内容高度可预估的场景,代码简洁易维护:
import { useState } from 'react'; function SlideToggle() { const [isOpen, setIsOpen] = useState(false); const toggleSlide = () => { setIsOpen(!isOpen); }; return ( <div className="slide-container"> <button onClick={toggleSlide} className="toggle-btn"> {isOpen ? '收起内容' : '展开内容'} </button> <div className={`slide-content ${isOpen ? 'open' : ''}`}> <p>这里是需要滑动展示的内容,支持任意长度的文本、列表或其他元素。</p> <p>额外内容示例,用于验证长文本场景下的滑动流畅度。</p> </div> </div> ); } export default SlideToggle;
对应的CSS样式:
.slide-container { width: 400px; margin: 20px auto; } .toggle-btn { padding: 8px 16px; cursor: pointer; border: none; background-color: #2196F3; color: white; border-radius: 4px; } .slide-content { overflow: hidden; max-height: 0; transition: max-height 0.3s ease-in-out; background-color: #f5f5f5; padding: 0 16px; margin-top: 8px; } .slide-content.open { max-height: 500px; /* 设置为足够容纳内容的数值,可按需调整 */ padding: 16px; }
2. 进阶版组件(动态计算内容高度)
如果内容高度不可预估,可通过useRef获取元素实际高度,动态设置max-height,避免固定值导致的动画延迟:
import { useState, useRef, useEffect } from 'react'; function SlideToggle() { const [isOpen, setIsOpen] = useState(false); const contentRef = useRef(null); const [contentHeight, setContentHeight] = useState(0); // 初始化时获取内容实际高度 useEffect(() => { if (contentRef.current) { setContentHeight(contentRef.current.scrollHeight); } }, []); const toggleSlide = () => { setIsOpen(!isOpen); }; return ( <div className="slide-container"> <button onClick={toggleSlide} className="toggle-btn"> {isOpen ? '收起内容' : '展开内容'} </button> <div ref={contentRef} className="slide-content" style={{ maxHeight: isOpen ? `${contentHeight}px` : '0' }} > <p>这里是需要滑动展示的内容,支持任意长度的文本、列表或其他元素。</p> <p>额外内容示例,用于验证长文本场景下的滑动流畅度。</p> </div> </div> ); } export default SlideToggle;
对应的CSS调整(移除.open类的max-height设置):
.slide-content { overflow: hidden; max-height: 0; transition: max-height 0.3s ease-in-out; background-color: #f5f5f5; padding: 0 16px; margin-top: 8px; } .slide-content.open { padding: 16px; }
常见问题原因
很多教程直接通过状态切换display属性,这种方式没有过渡动画,会瞬间显示/隐藏;还有部分尝试过渡height: auto,但CSS不支持auto值的过渡,导致效果生硬。而max-height的过渡可以完美模拟滑动效果,同时保持流畅。
内容的提问来源于stack exchange,提问作者Ren Jitsm
相关产品推荐
相关产品推荐

