如何使用react-transition-group实现Reach Router Redirect跳转动画并解决报错
异常产生原因
- 你在
useEffect同步回调中执行的命令式redirectTo重定向,触发路由变更的时机过早,早于CSSTransition完成当前组件入场动画绑定的时机。TransitionGroup通过子元素的key变化触发动画队列,当路由在同一渲染周期内连续变更时,旧节点还没被注册到动画实例就被卸载,框架尝试给不存在的DOM节点添加退场动画类时就会抛出对应报错,动画也无法正常触发。 - 你当前使用的
CSSTransition没有配置unmountOnExit属性,退场动画完成后旧路由组件不会自动卸载,也会干扰路由切换时的动画识别逻辑。
修复方案
方案1:替换为声明式重定向(最优)
修改ProfileScreen逻辑,删除useEffect中的命令式跳转,直接在渲染阶段判断token是否存在,不存在就返回Redirect组件,由react-router统一调度路由变更,天然适配TransitionGroup的生命周期。修改后代码如下:
const ProfileScreen: FunctionComponent<RouteComponentProps> = (props) => { const location = useLocation(); const urlParams = new URLSearchParams(location.search.substring(1)); const token = urlParams.get('token'); if (!token) { return <Redirect to={routes.auth} />; } return ( <> <h1>Hello!</h1> </> ); };
方案2:补全CSSTransition配置
给App组件中的CSSTransition添加unmountOnExit和appear属性,保证动画执行逻辑正常:
<CSSTransition key={location.key} timeout={150} classNames={classNames} unmountOnExit appear >
方案3:命令式跳转兼容方案
如果业务逻辑必须在useEffect中执行跳转,可以给跳转逻辑加150ms延迟,和你配置的动画超时时间保持一致,等当前组件入场动画绑定完成后再触发路由变更:
useEffect(() => { if (!token) { setTimeout(() => redirectTo(routes.auth), 150); } }, [token]);
内容的提问来源于stack exchange,提问作者Вениамин Трепачко
相关产品推荐
相关产品推荐

