为什么React的CSSTransition在页面切换时动画不连贯?

司空树恺 阅读 7

大家好,我在用React做路由切换动画时遇到问题。用了CSSTransition包裹路由组件,设置进入和离开的CSS类,但切换时动画总是先跳一下再执行过渡效果,这是为什么呢?

我尝试过给容器加fixed定位,调整z-index,还试过在组件挂载后再触发动画,但点击导航切换页面时,新页面内容还是会先闪现一下原位置…

这是我的代码片段:


<CSSTransition
  key={location.pathname}
  timeout={300}
  classNames="page"
  unmountOnExit
>
  <Outlet />
</CSSTransition>

对应的CSS用了:


.page-enter-active { transition: all 0.3s ease; }
.page-enter { opacity: 0; transform: translateY(50px); }
.page-exit-active { transition: all 0.3s ease; }
.page-exit { opacity: 0; transform: translateY(-50px); }

有没有同学遇到过类似情况?是定位方式不对还是过渡逻辑有问题?

我来解答 赞 4 收藏
二维码
手机扫码查看
1 条解答
百里丽君
这个问题主要是因为React的CSSTransition在处理路由切换时,新旧组件的渲染时机导致的。官方文档里提到过,CSSTransition是通过添加和移除CSS类来控制过渡效果的,但如果没有正确设置初始状态,确实会出现你描述的“闪现”问题。

关键点在于,进入动画开始之前,新组件已经完成了首次渲染,所以会出现一瞬间的布局跳变。解决方法是确保进入动画的初始状态(也就是 page-enter 类)在组件挂载时就已经生效,而不是等到React完成渲染后才应用。

推荐的做法是在外层容器上显式地定义样式,强制让新组件一开始就处于动画的起始位置。比如:

.page-enter {
opacity: 0;
transform: translateY(50px);
position: absolute;
width: 100%;
}
.page-enter-active {
opacity: 1;
transform: translateY(0);
transition: all 0.3s ease;
}
.page-exit {
opacity: 1;
transform: translateY(0);
}
.page-exit-active {
opacity: 0;
transform: translateY(-50px);
transition: all 0.3s ease;
}


另外,注意你的 CSSTransition 外层容器需要有相对定位或者固定定位,否则 position: absolute 不会生效。比如这样:

<div style={{ position: 'relative' }}>
<CSSTransition
key={location.pathname}
timeout={300}
classNames="page"
unmountOnExit
>
<Outlet />
</CSSTransition>
</div>


最后提醒一点,如果你用的是React Router,确保 location.pathname 的值能唯一标识每个页面,不然 key 值不变会导致CSSTransition无法正确触发。

我之前也被这个问题坑过好几次,尤其是调试的时候总觉得是CSS写错了,结果发现是React的渲染机制搞的鬼。调整完这些配置后,动画应该就能流畅衔接了。
点赞
2026-02-18 13:01