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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 05:40:14