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

Framer Motion关闭条件渲染组件时无过渡效果求助

问题分析与修复方案

你的代码存在几个关键问题,导致侧边栏关闭时无过渡效果:

1. Exit 变体未正确绑定

你定义了exit动画变体,但组件的exit属性设置为"hidden",这会导致关闭时无法触发你配置的退出动画逻辑,需改为"exit"。

2. 条件渲染导致组件被提前移除

当前{cartBarOpen && <CartContainer />}的写法,会在cartBarOpen变为false时立刻将组件从DOM中移除,AnimatePresence来不及播放退出动画。AnimatePresence的核心作用就是等待组件完成退出动画后再移除DOM,无需手动控制时机。

3. 冗余的 setTimeout 与 animate 属性设置

  • animate属性无需根据cartBarOpen动态切换,直接设为"visible"即可,初始状态由initial="hidden"控制,退出状态由exit="exit"控制。
  • handleCloseCart中的setTimeout完全多余,直接dispatch关闭动作即可,AnimatePresence会自动等待动画结束后移除组件。

4. 缺少唯一标识 key

AnimatePresence需要组件拥有唯一key属性,确保它能正确识别组件的进出状态。


修复后的代码

const { cartBarOpen } = useSelector((rootReducer: any) => rootReducer.cartBarReducer)

const handleCloseCart = () => {
    dispatch({ type: cartBarActionTypes.CLOSE });
};

const containerVariants = {
    hidden: {
        x: "100%"
    },
    visible: {
        x: 0,
        transition: {
            duration: 0.5,
            type: 'tween',
            ease: 'easeInOut'
        }
    },
    exit: {
        x: "100%",
        transition: {
            duration: 0.5,
            type: 'tween',
            ease: 'easeInOut'
        }
    },
};

return (
    <>
        <AnimatePresence>
            {cartBarOpen && (
                <CartContainer
                    key="cart-sidebar"
                    variants={containerVariants}
                    initial="hidden"
                    animate="visible"
                    exit="exit"
                >
                    <ContainerTop>
                        <CartTitle>Carrinho de Compras</CartTitle>
                        <CloseCart onClick={handleCloseCart}>X</CloseCart>
                    </ContainerTop>
                    <CartContent>
                    </CartContent>
                    <ContainerBottom>
                    </ContainerBottom>
                </CartContainer>
            )}
        </AnimatePresence>
    </>
);

额外注意事项

  • 确保CartContainer是Framer Motion的motion组件(如motion.div),如果是用styled-components封装的,需转换为motion组件:
    import styled from 'styled-components';
    import { motion } from 'framer-motion';
    
    const CartContainer = styled(motion.div)`
        // 你的样式代码
    `;
    

内容的提问来源于stack exchange,提问作者Daniel Gonçalves dos Santos

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 21:42:34