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

如何让Framer Motion仅在initial与animate间循环动画,exit动画仅播放一次?

解决Framer Motion中AnimatePresence的无限循环exit动画问题

问题核心:当给组件的initial→animate过渡设置repeat: Infinity后,组件卸载时exit动画会继承这个重复属性,导致无限循环。之前用isLoading控制repeat的方式无效,是因为组件触发卸载流程时,状态更新无法及时覆盖过渡配置,且共用的过渡会让exit继承重复规则。

正确方案:为不同状态单独指定过渡配置

不要共用同一个transition属性,而是给animate状态单独设置无限重复的过渡,exit状态单独设置无重复的过渡。这样就能保证只有加载阶段的动画循环,卸载时只执行一次退出动画。

写法1:直接给exit指定exitTransition

<AnimatePresence>
  {isLoading && (
    <motion.div
      initial={{ opacity: 0.5 }}
      animate={{ opacity: 0.8 }}
      // 仅initial到animate的过渡用无限重复
      transition={{ repeatType: 'reverse', repeat: Infinity }}
      exit={{ opacity: 0 }}
      // exit动画单独配置,关闭重复
      exitTransition={{ repeat: 0, duration: 0.3 }} // 可自定义退出动画时长
    >
      {children}
    </motion.div>
  )}
</AnimatePresence>

写法2:使用variants拆分状态配置

这种方式更清晰,适合复杂动画场景:

<AnimatePresence>
  {isLoading && (
    <motion.div
      initial="initial"
      animate="animate"
      exit="exit"
      variants={{
        initial: { opacity: 0.5 },
        animate: {
          opacity: 0.8,
          transition: { repeatType: 'reverse', repeat: Infinity }
        },
        exit: {
          opacity: 0,
          transition: { repeat: 0 } // 明确关闭重复
        }
      }}
    >
      {children}
    </motion.div>
  )}
</AnimatePresence>

原理说明

Framer Motion中,如果没有单独指定exitTransition或在variants中为exit状态设置过渡,exit动画会继承通用的transition配置。所以只要确保exit状态的过渡不包含repeat: Infinity,就能避免卸载时的无限循环。

内容的提问来源于stack exchange,提问作者basarat

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 14:42:58