Framer Motion错误动画仅触发一次问题及解决方案咨询
解决Framer Motion错误动画仅触发一次的问题
问题根源
你在nextHandler里先执行setError(false),紧接着又setError(true),React会把这两次同步状态更新批处理合并,最终error状态相当于没有发生可检测的变化(从true→false→true,合并后等于没动),所以Framer Motion不会重新触发动画。
解决方案一:拆分状态更新时机
通过setTimeout延迟设置error为true,让React能完整处理两次状态变化:
const nextHandler = () => { setError(false); if (!validate(value, [VALIDATION_TYPE.REQUIRE, VALIDATION_TYPE.MAX_LENGTH(5)])) { setTimeout(() => { setError(true); }, 0); toast.error(ERROR_MESSAGES.invalid_name); return; } nextStepHandler(); };
解决方案二:用强制重渲染触发动画
新增一个animationKey状态,每次验证失败时更新这个key,让React重新创建motion.input组件,强制触发动画:
const [animationKey, setAnimationKey] = useState(0); const [error, setError] = useState(false); const nextHandler = () => { if (!validate(value, [VALIDATION_TYPE.REQUIRE, VALIDATION_TYPE.MAX_LENGTH(5)])) { setError(true); setAnimationKey(prev => prev + 1); toast.error(ERROR_MESSAGES.invalid_name); return; } setError(false); nextStepHandler(); };
然后给motion.input加上key属性:
<motion.input key={animationKey} type="text" id="userName" name="userName" autoComplete="off" value={value} onChange={inputHandler} initial={false} animate={{ borderColor: error ? 'red' : 'initial', x: error ? [-2, 2, -2, 2, 0] : 0, }} transition={{ duration: 0.5 }} />
说明
方案一利用React的异步更新机制,让两次状态变化被分别处理;方案二通过改变组件key强制重渲染,两种方法都能让动画每次验证失败时都触发。
内容的提问来源于stack exchange,提问作者gndy Br
相关产品推荐
相关产品推荐

