基于react-spring实现依赖props的多步骤表单条件渲染动画
实现方案
你当前的实现问题在于useSpring的配置没有和step状态绑定,仅会在组件首次挂载时触发一次淡入动画,步骤切换时不会重新触发动画,也没有处理旧步骤的退场过渡。推荐使用react-spring的useTransitionAPI实现,这是处理动态元素切换动画的专用方案,可以完全替代你之前用的react-transition-group的能力,完整可运行代码如下:
import React, { useState } from 'react'; import { animated, useTransition } from 'react-spring'; function MultiStepForm() { const [step, setStep] = useState(1); // 总步骤数,根据你的实际需求调整 const totalSteps = 3; // 绑定step状态作为过渡触发器 const transitions = useTransition(step, { // 进场动画配置 from: { opacity: 0, transform: 'translateX(20px)' }, // 进场完成后状态 enter: { opacity: 1, transform: 'translateX(0)' }, // 退场动画配置 leave: { opacity: 0, transform: 'translateX(-20px)' }, // 动画时长,可自定义 config: { duration: 200 }, }); // 步骤切换方法,绑定到下一步/上一步按钮即可 const handleStepChange = (direction) => { setStep(prev => { const newStep = direction === 'next' ? prev + 1 : prev - 1; // 边界判断,防止超出步骤范围 if (newStep < 1 || newStep > totalSteps) return prev; return newStep; }); }; return ( <div className="form-wrapper"> {transitions((style, currentStep) => ( <animated.div style={style} className="step-container"> {/* 按当前步骤渲染对应内容,替换为你的实际表单步骤 */} {currentStep === 1 && <div>步骤1:填写基础信息</div>} {currentStep === 2 && <div>步骤2:填写账号信息</div>} {currentStep === 3 && <div>步骤3:完成提交</div>} </animated.div> ))} {/* 操作按钮示例 */} <div className="action-buttons"> <button onClick={() => handleStepChange('prev')} disabled={step === 1}>上一步</button> <button onClick={() => handleStepChange('next')} disabled={step === totalSteps}>下一步</button> </div> </div> ); }
补充说明
- 如果你只需要淡入淡出效果,删掉代码中
transform相关配置仅保留opacity即可 - 如果你的步骤组件是单独封装的,直接把对应组件放到对应步骤的渲染逻辑里即可,不需要额外修改组件代码
- 如果你确实只想用
useSpring实现(仅支持进场淡入,无退场动画),可以修改原有代码如下:
import React, { useState} from 'react'; import { animated, useSpring } from 'react-spring'; const AnimatedContainer = animated.div function MultiStepForm() { const [step, setStep] = useState(1); // 把step作为依赖项,每次step变化时重新触发动画 const style = useSpring({ to: {opacity: 1}, from: {opacity: 0}, config: { duration: 200 }, // 关键配置:依赖step变化重置动画 reset: true }, [step]) return ( <AnimatedContainer style={style}> {step === 1 && <div>步骤1内容</div>} {step === 2 && <div>步骤2内容</div>} {step === 3 && <div>步骤3内容</div>} </AnimatedContainer> ) }
内容的提问来源于stack exchange,提问作者Gabriel
相关产品推荐
相关产品推荐

