React Router使用Link切换嵌套路由时父组件卸载如何解决?
更新:这段代码存在问题,我已在下方给出解答
问题根因
你观察到的Dashboard组件“卸载”是两个常见问题叠加导致的:
- 所有组件内的
useEffect都没有传入空依赖数组。按照React Hooks规则,不传依赖数组的useEffect会在每一次组件重渲染时执行:先触发返回的清理函数,再执行副作用逻辑,所以控制台会打印dashboard unmounted后紧跟dashboard mounted,看起来就像组件被卸载重建,实际上Dashboard全程没有真的卸载。 - 如果你确认组件真的被卸载,大概率是项目使用了React Router v6版本,原有v5的路由API不兼容导致路由匹配失败,父组件被卸载。
修复方案
场景1:使用React Router v5
只需要给所有useEffect添加空依赖数组[],指定副作用仅在组件挂载、卸载时执行即可:
// Dashboard组件修正 function Dashboard({ match }) { useEffect(() => { console.log("dashboard mounted"); return () => console.log("dashboard unmounted"); }, []); // 新增空依赖数组 return ( <div> <Switch> <Route exact path={`${match.path}`} component={Home} /> <Route exact path={`${match.path}/chat`} component={Chat} /> </Switch> </div> ); } // Home组件修正 function Home({ match }) { useEffect(() => { console.log("home mounted"); return () => console.log("home unmounted"); }, []); // 新增空依赖数组 return ( <div> <h3>home component</h3> <Link to={`${match.url}/chat`}> <button>chat</button> </Link> </div> ); } // Chat组件修正 function Chat() { useEffect(() => { console.log("chat mounted"); return () => console.log("chat unmounted"); }, []); // 新增空依赖数组 return ( <div> <h3>Chat component</h3> </div> ); }
场景2:使用React Router v6
v6版本废弃了原有Switch、component属性等API,需要适配新写法:
外层App组件修改:
import { BrowserRouter as Router, Routes, Route, Navigate } from 'react-router-dom'; export default function App() { return ( <Router> <div> <hr /> <Routes> <Route path="/" element={<Navigate to="/dashboard" replace />} /> {/* 嵌套路由父路径需要加*通配符 */} <Route path="/dashboard/*" element={<Dashboard />} /> <Route path="*" element={<h1>not found</h1>} /> </Routes> </div> </Router> ); }
Dashboard组件修改:
import { Routes, Route } from 'react-router-dom'; function Dashboard() { useEffect(() => { console.log("dashboard mounted"); return () => console.log("dashboard unmounted"); }, []); return ( <div> <Routes> {/* 子路由直接写相对路径即可 */} <Route path="" element={<Home />} /> <Route path="chat" element={<Chat />} /> </Routes> </div> ); }
修改完成后切换路由,Dashboard不会再触发卸载日志,也不会真的被卸载。
内容的提问来源于stack exchange,提问作者sunil Prajapat
相关产品推荐
相关产品推荐

