You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Router使用Link切换嵌套路由时父组件卸载如何解决?

更新:这段代码存在问题,我已在下方给出解答

问题根因

你观察到的Dashboard组件“卸载”是两个常见问题叠加导致的:

  1. 所有组件内的useEffect都没有传入空依赖数组。按照React Hooks规则,不传依赖数组的useEffect会在每一次组件重渲染时执行:先触发返回的清理函数,再执行副作用逻辑,所以控制台会打印dashboard unmounted后紧跟dashboard mounted,看起来就像组件被卸载重建,实际上Dashboard全程没有真的卸载。
  2. 如果你确认组件真的被卸载,大概率是项目使用了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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.12 22:03:02