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

React组件挂载/卸载时实现级联交错动画效果问题求解

React 侧边栏交错动画稳定实现方案

用 Framer Motion 原生的变体编排能力即可实现,不需要混用 spring、css transition 等多套方案,核心是通过容器的动画编排参数自动处理子元素时序,完全不需要手动给每个元素写延迟值。

核心实现逻辑

  • 侧边栏容器用AnimatePresence包裹,基于挂载/卸载状态自动触发滑入滑出动画,不需要额外按钮控制
  • 容器动画变体配置staggerChildren参数统一控制子元素交错间隔,通过staggerDirection切换滑入/滑出时的交错顺序:滑入时从上到下正序淡入,滑出时从下到上倒序淡出
  • 通过when参数绑定容器和子元素的动画执行时机,避免容器和内容动画时序错乱

可直接复用的核心代码

import { useState } from 'react';
import { motion, AnimatePresence } from 'framer-motion';

export default function SidebarDemo() {
  const [isOpen, setIsOpen] = useState(false);

  // 侧边栏容器动画配置
  const sidebarVariants = {
    hidden: {
      x: '100%',
      transition: {
        staggerChildren: 0.07,
        staggerDirection: -1,
        when: 'afterChildren'
      }
    },
    visible: {
      x: 0,
      transition: {
        staggerChildren: 0.07,
        staggerDirection: 1,
        when: 'beforeChildren'
      }
    }
  };

  // 内部标题通用动画配置
  const contentVariants = {
    hidden: { opacity: 0, x: 16 },
    visible: { opacity: 1, x: 0 }
  };

  return (
    <div className="page">
      {/* 触发元素 */}
      <div className="trigger" onClick={() => setIsOpen(true)}>
        Information
      </div>

      <AnimatePresence>
        {isOpen && (
          <motion.aside
            className="sidebar"
            variants={sidebarVariants}
            initial="hidden"
            animate="visible"
            exit="hidden"
            onClick={() => setIsOpen(false)}
          >
            <motion.h1 variants={contentVariants}>主标题</motion.h1>
            <motion.h3 variants={contentVariants}>二级模块标题</motion.h3>
            <motion.h5 variants={contentVariants}>辅助说明文本</motion.h5>
          </motion.aside>
        )}
      </AnimatePresence>
    </div>
  );
}

关键参数说明:

  • when: 'beforeChildren':滑入时先执行子元素的交错淡入,再完成容器的位移动画,避免内容提前露在容器外
  • when: 'afterChildren':滑出时等所有子元素完成交错淡出,再执行容器的滑出动画,避免内容还没消失容器就先移走
  • staggerDirection: 1/-1:自动切换子元素动画的触发顺序,不需要单独给滑入滑出写两套子元素延迟配置

之前实现不稳定的常见原因

  • 没有用AnimatePresence包裹条件渲染的侧边栏,导致组件卸载时直接被移除,根本不会执行退出阶段的滑出、淡出动画
  • 手动给每个标题写死transition.delay值,滑入滑出共用同一套延迟,导致滑出时淡出顺序和预期不符
  • 没有绑定容器和子元素的动画执行时机,出现容器动画和内容动画互相抢时序的问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 01:18:24