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

React中卡片切换场景的过渡动画实现方案咨询

React卡片选择场景下过渡动画实现思路

我在React项目中实现了卡片选择功能:通过selectedServiceIndex和isServiceSelected两个state跟踪选中状态,点击卡片时切换状态——初始显示全部服务卡片,选中后仅展示选中的单张卡片。功能逻辑正常,但切换时原<section className="section services-section" id="services">节点会被移除,无法为其设置淡出等过渡动画,以下是几种可行的实现思路:


核心原则:避免直接卸载目标节点,通过状态控制动画

方案1:CSS类切换+保留DOM节点

不要用条件渲染直接移除整个section,而是始终保留该节点,通过isServiceSelected状态给它添加切换类,控制过渡效果:

  1. 编写过渡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); }
}
  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:

  1. 安装依赖:
npm install react-transition-group
  1. 包裹需要过渡的节点:
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>
)}
  1. 编写对应过渡样式:
/* 服务列表淡出动画 */
.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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 19:24:58