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

React/Framer Motion:子元素Stagger动画未生效问题排查

Framer Motion 子元素错开动画失效问题解决

问题背景

我正在金融服务应用中构建余额概览功能,通过向单个<BalanceEntry>组件传递props并映射所有条目渲染内容。想让每个<BalanceEntry>的入场动画错开0.2秒,但目前所有条目总是成组动画,无法实现逐个延迟入场。

当前代码:

<div className="pt-16">
  <motion.div
    initial={{ opacity: 0, y: -20 }}
    animate={{ opacity: 1, x: 1 }}
    transition={{
      delay: 0.3,
      default: { ease: 'easeInOut' },
      staggerChildren: 0.2,
    }}
  >
    {TransactionData.map((item) => {
      return (
        <div key={item.id}>
          <motion.div variants={BalanceEntryVariants}>
            <BalanceEntry
              transactionDate={item.transactionDate}
              transactionType={item.transactionType}
              transactionID={item.transactionID}
              transactionAmount={item.transactionAmount}
              transactionIcon={item.transactionIcon}
            />
          </motion.div>
        </div>
      );
    })}
  </motion.div>
</div>

变体配置:

const BalanceEntryVariants = {
  hidden: {
    opacity: 0,
    y: -20,
  },
  visible: {
    opacity: 1,
    x: 1,
    transition: {
      ease: 'easeInOut',
    },
  },
};

错误原因

  • 父容器未关联变体触发逻辑:你给父motion.div设置了staggerChildren,但父容器既没定义自己的variants,也没将initial/animate指定为变体状态名,导致子元素的动画无法被父容器的错开规则控制。
  • 子元素未启用状态切换:子motion.div仅传入了variants,但没设置initial和animate属性,无法触发hidden到visible的动画状态变化。
  • 额外包裹div阻断动画层级:父motion.div和子motion.div之间的普通<div>,导致子motion.div不再是父容器的直接子级——而staggerChildren只对父容器的直接子级motion元素生效,错开效果因此失效。

修正方案

调整后的完整代码

<div className="pt-16">
  {/* 父容器使用变体定义,并绑定状态触发错开规则 */}
  <motion.div
    variants={{
      hidden: { opacity: 0 },
      visible: { 
        opacity: 1,
        transition: {
          delay: 0.3,
          staggerChildren: 0.2,
          ease: 'easeInOut'
        }
      }
    }}
    initial="hidden"
    animate="visible"
  >
    {TransactionData.map((item) => {
      return (
        {/* 移除多余包裹div,让子motion.div成为父容器直接子级 */}
        <motion.div 
          key={item.id}
          variants={BalanceEntryVariants}
          initial="hidden"
          animate="visible"
        >
          <BalanceEntry
            transactionDate={item.transactionDate}
            transactionType={item.transactionType}
            transactionID={item.transactionID}
            transactionAmount={item.transactionAmount}
            transactionIcon={item.transactionIcon}
          />
        </motion.div>
      );
    })}
  </motion.div>
</div>

变体配置保持不变

const BalanceEntryVariants = {
  hidden: {
    opacity: 0,
    y: -20,
  },
  visible: {
    opacity: 1,
    x: 1,
    transition: {
      ease: 'easeInOut',
    },
  },
};

说明

修正后,父容器通过variants定义状态,并在visible状态的过渡中设置staggerChildren;子motion.div直接作为父容器的子级,同时绑定initial和animate状态,这样就能触发每个条目依次延迟0.2秒入场的动画效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 16:31:17