如何阻止TanStack Router路由切换时重新挂载整个组件树?
解决TanStack Router中组件重复挂载导致动画失效的问题
针对你遇到的情况,有两个直接有效的方案:
方案一:路由嵌套重构(推荐)
把Tabs组件提升到父路由/user/$userId中,让子路由只负责渲染对应标签页的内容部分。这样Tabs组件只会在进入/user/$userId时挂载一次,切换子路由时只会更新内容区域,完全不会触发Tabs的重新挂载,动画自然能正常运行。
示例代码如下:
// 父路由组件 function UserLayout() { const { userId } = useParams(); const { matches } = useRouter(); // 匹配当前激活的子路由,用来高亮对应标签 const activeTab = matches[1].pathname.split('/').pop(); return ( <div> <Tabs activeTab={activeTab}> <TabItem label="个人资料" to={`/user/${userId}/profile`} /> <TabItem label="历史记录" to={`/user/${userId}/history`} /> <TabItem label="排行榜" to={`/user/${userId}/ranking`} /> </Tabs> {/* 渲染子路由内容 */} <Outlet /> </div> ); } // 路由配置 const router = createRouter({ routes: [ { path: '/user/$userId', component: UserLayout, children: [ { path: 'profile', component: ProfilePage }, { path: 'history', component: HistoryPage }, { path: 'ranking', component: RankingPage }, ], }, ], });
方案二:手动固定组件Key
如果不想重构路由结构,也可以给Tabs组件手动指定一个固定的key,让React认为这是同一个组件实例,避免重新挂载。比如基于userId来设置key,因为同一个用户下的标签切换,userId是不变的:
// 在每个子路由组件中 function ProfilePage() { const { userId } = useParams(); return <Tabs key={`user-tabs-${userId}`} activeTab="profile" />; } function HistoryPage() { const { userId } = useParams(); return <Tabs key={`user-tabs-${userId}`} activeTab="history" />; }
这样不管切换到哪个子路由,Tabs组件的key都是相同的,React就会复用之前的组件实例,动画效果就能保留了。
内容的提问来源于stack exchange,提问作者King Witcher
相关产品推荐
相关产品推荐

