React中卡片切换场景的过渡动画实现方案咨询
React卡片选择场景下过渡动画实现思路
我在React项目中实现了卡片选择功能:通过selectedServiceIndex和isServiceSelected两个state跟踪选中状态,点击卡片时切换状态——初始显示全部服务卡片,选中后仅展示选中的单张卡片。功能逻辑正常,但切换时原<section className="section services-section" id="services">节点会被移除,无法为其设置淡出等过渡动画,以下是几种可行的实现思路:
核心原则:避免直接卸载目标节点,通过状态控制动画
方案1:CSS类切换+保留DOM节点
不要用条件渲染直接移除整个section,而是始终保留该节点,通过isServiceSelected状态给它添加切换类,控制过渡效果:
- 编写过渡CSS:
.services-section { transition: all 0.3s ease; opacity: 1; transform: translateY(0); height: auto; overflow: visible; } .services-section--hidden { opacity: 0; transform: translateY(20px); pointer-events: none; height: 0; overflow: hidden; } .selected-service-section { animation: fadeInScale 0.3s ease forwards; } @keyframes fadeInScale { from { opacity: 0; transform: scale(0.9); } to { opacity: 1; transform: scale(1); } }
- React组件中应用:
<section className={`section services-section ${isServiceSelected ? 'services-section--hidden' : ''}`} id="services" > {/* 全部服务卡片内容 */} </section> {isServiceSelected && ( <section className="selected-service-section"> {/* 选中的单张卡片内容 */} </section> )}
方案2:使用React Transition Group管理卸载动画
借助react-transition-group的CSSTransition组件,它会在组件卸载前等待动画完成再移除DOM:
- 安装依赖:
npm install react-transition-group
- 包裹需要过渡的节点:
import { CSSTransition } from 'react-transition-group'; <CSSTransition in={!isServiceSelected} timeout={300} classNames="service-list" unmountOnExit > <section className="section services-section" id="services"> {/* 全部服务卡片内容 */} </section> </CSSTransition> {isServiceSelected && ( <CSSTransition in={isServiceSelected} timeout={300} classNames="selected-service" unmountOnExit > <section className="selected-service-section"> {/* 选中的单张卡片内容 */} </section> </CSSTransition> )}
- 编写对应过渡样式:
/* 服务列表淡出动画 */ .service-list-exit { opacity: 1; transform: translateY(0); } .service-list-exit-active { opacity: 0; transform: translateY(20px); transition: opacity 0.3s ease, transform 0.3s ease; } /* 选中卡片入场动画 */ .selected-service-enter { opacity: 0; transform: scale(0.9); } .selected-service-enter-active { opacity: 1; transform: scale(1); transition: opacity 0.3s ease, transform 0.3s ease; }
方案3:统一容器内部切换过渡
用一个固定容器包裹两种状态的内容,通过控制内部元素的堆叠和过渡实现切换:
<section className="services-container"> {/* 全部卡片容器 */} <div className={`services-grid ${isServiceSelected ? 'services-grid--hidden' : ''}`} > {/* 全部服务卡片 */} </div> {/* 选中卡片容器 */} <div className={`selected-card ${isServiceSelected ? 'selected-card--show' : ''}`} > {/* 选中的单张卡片 */} </div> </section>
CSS示例:
.services-container { position: relative; min-height: 400px; /* 根据内容设置最小高度 */ } .services-grid, .selected-card { position: absolute; width: 100%; transition: all 0.3s ease; } .services-grid--hidden { opacity: 0; transform: scale(0.95); pointer-events: none; } .selected-card { opacity: 0; transform: translateY(20px); } .selected-card--show { opacity: 1; transform: translateY(0); }
内容的提问来源于stack exchange,提问作者Gabi
相关产品推荐
相关产品推荐

