Collapse折叠动画在React中为什么高度过渡不生效?

开发者雨萓 阅读 66

我用React写了个Collapse组件,想实现点击展开/收起时的高度平滑过渡,但动画完全没效果,直接闪现。试过加transition和maxHeight,还是不行,是不是哪里逻辑错了?

这是我的代码:

const Collapse = ({ isOpen, children }) => {
  return (
    <div
      style={{
        height: isOpen ? 'auto' : 0,
        overflow: 'hidden',
        transition: 'height 0.3s ease'
      }}
    >
      {children}
    </div>
  );
};
我来解答 赞 16 收藏
二维码
手机扫码查看
1 条解答
司马可馨
问题很简单:CSS transition 不支持 height: auto 的过渡,浏览器不知道怎么从 0 变到 auto,所以直接闪现了。

解决方法是用 scrollHeight 动态获取内容实际高度:

const Collapse = ({ isOpen, children }) => {
const contentRef = React.useRef(null);
const [height, setHeight] = React.useState(0);

React.useEffect(() => {
if (isOpen) {
const scrollHeight = contentRef.current.scrollHeight;
setHeight(scrollHeight);
} else {
setHeight(0);
}
}, [isOpen]);

return (
<div
style={{
height: height,
overflow: 'hidden',
transition: 'height 0.3s ease'
}}
>
<div ref={contentRef}>
{children}
</div>
</div>
);
};


核心思路就是:展开时先获取内容的实际 scrollHeight,赋值给 height;收起时设回 0。这样 transition 就能正常工作了,因为此时 height 是具体数值而不是 auto。

如果担心展开时内容高度会变(比如异步加载数据),可以在数据更新后重新计算 height,用 ResizeObserver 监听或者在数据变化时再设一次。

另外注意,外层容器的高度变化是立即触发的,所以 children 最好包一层 ref,样式别写在外层容器上。
点赞
2026-03-17 21:18