React条件渲染状态切换时过渡动画失效问题排查
问题分析与解决方案
你的过渡动画不生效的核心原因是:当driversDiscount为false时,目标div被直接从DOM中移除了,没有给CSS过渡提供从opacity-0到opacity-100(或反之)的状态变化过程,动画自然无法触发。
修复方案一:保留DOM元素,用CSS类控制显隐(Tailwind原生实现)
不用条件渲染移除元素,而是始终渲染目标区块,通过driversDiscount状态切换对应的Tailwind类来控制透明度和可见性,让CSS过渡能捕捉到状态变化:
//Imports const DriversDetails= () => { const [driversDiscount,setDriversDiscount]=useState(false) const [removeCents, setRemoveCents] = useState(false); // 补充缺失的状态定义 return ( <> <label htmlFor="" className="flex items-center gap-2 text-[#6F6464] font-semibold pb-2"> <ToggleButton value={driversDiscount} action={setDriversDiscount}/> Do you want to offer discounts? <ExclIcon/> </label> {/* 移除条件渲染,用类切换控制显隐 */} <div className={`flex justify-between pb-4 transition-all duration-500 ease-in-out ${ driversDiscount ? 'opacity-100 visible' : 'opacity-0 invisible' }`}> <div> <p className="font-semibold text-black-primary pb-1">Total amount <span className="text-[12px] text-black-light">(After discount)</span></p> <p className="text-[14px] font-semibold text-black-light flex gap-2 items-center "> <ToggleButton value={removeCents} action={setRemoveCents} />Remove cents </p> </div> <p className="text-right"> <span className='font-[700] text-[18px] ml-1'> $8</span> <span className='text-[#151515] text-sm font-medium'>.29</span> </p> </div> </> ); } export default DriversDetails;
opacity-0/opacity-100控制透明度过渡invisible/visible控制元素是否可交互(invisible会保留元素布局空间,避免页面跳动)- 如果需要完全隐藏且不占空间,可以替换为:
注意要给driversDiscount ? 'opacity-100 h-auto' : 'opacity-0 h-0 overflow-hidden'transition-all包含height属性的过渡。
修复方案二:使用条件渲染+过渡组件(适合需要完全移除DOM的场景)
如果必须在状态为false时移除DOM,可以使用react-transition-group的CSSTransition组件来包裹目标区块,手动控制过渡阶段:
- 先安装依赖:
npm install react-transition-group
- 修改代码:
//Imports import { CSSTransition } from 'react-transition-group'; const DriversDetails= () => { const [driversDiscount,setDriversDiscount]=useState(false) const [removeCents, setRemoveCents] = useState(false); return ( <> <label htmlFor="" className="flex items-center gap-2 text-[#6F6464] font-semibold pb-2"> <ToggleButton value={driversDiscount} action={setDriversDiscount}/> Do you want to offer discounts? <ExclIcon/> </label> <CSSTransition in={driversDiscount} timeout={500} classNames="discount-transition" unmountOnExit > <div className="flex justify-between pb-4"> {/* 内容不变 */} <div> <p className="font-semibold text-black-primary pb-1">Total amount <span className="text-[12px] text-black-light">(After discount)</span></p> <p className="text-[14px] font-semibold text-black-light flex gap-2 items-center "> <ToggleButton value={removeCents} action={setRemoveCents} />Remove cents </p> </div> <p className="text-right"> <span className='font-[700] text-[18px] ml-1'> $8</span> <span className='text-[#151515] text-sm font-medium'>.29</span> </p> </div> </CSSTransition> </> ); } export default DriversDetails;
- 在CSS中添加过渡样式:
.discount-transition-enter { opacity: 0; } .discount-transition-enter-active { opacity: 1; transition: opacity 500ms ease-in-out; } .discount-transition-exit { opacity: 1; } .discount-transition-exit-active { opacity: 0; transition: opacity 500ms ease-in-out; }
内容的提问来源于stack exchange,提问作者Abu RayhaN
相关产品推荐
相关产品推荐

