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

React-Router-DOM v6.27中NavBar重复渲染丢失状态的解决方法

解决React-Router-DOM v6中NavBar路由切换时重新渲染丢失状态的问题

问题根源

你当前代码里的Application组件被定义在App组件内部,每次App组件重新渲染(比如主题切换、上下文更新等场景),React会判定这是一个全新的组件类型,会卸载原有的Application及其子组件(包括NavBar),再重新挂载新实例,直接导致NavBar的状态(如折叠状态)丢失。

重构方案

1. 提取Application为独立组件

把Application从App内部移出来,作为单独的顶层组件,这样它的组件引用不会随App的渲染而改变,React会保留它的实例和内部状态。

2. 传递必要依赖

如果Application需要使用App中的资源(比如QueryFeedback),通过props传递给它即可。

修改后的完整代码

// 提取为独立组件
const Application = ({ QueryFeedback }) => {
  return (
    <AuthenticatedView>
      <div className="app">
        <NavBar />
        <div className="content">
          <Topbar />
          <main className="view">
            <Outlet />
          </main>
        </div>
        <QueryFeedback />
      </div>
    </AuthenticatedView>
  );
};

function App() {
  const [theme, colorMode] = useMode();
  const { QueryFeedback, queryClient } = useFeedbackQuery();

  return (
    <QueryClientProvider client={queryClient}>
      <ColorModeContext.Provider value={colorMode}>
        <ThemeProvider theme={theme}>
          <CssBaseline />
          <Routes>
            <Route path="/" element={<Application QueryFeedback={QueryFeedback} />}>
              <Route index element={<Dashboard />} />
              <Route path="courses" element={<Courses />} />

              <Route path="course/:id" element={<CourseView />}>
                <Route path="" element={<CourseDetail />} />
                <Route path=":moduleid" element={<ModuleDetail />} />
              </Route>

              <Route path="announcements" element={<Announcements />} />
              <Route path="calendar" element={<Calendar />} />

              <Route path="*" element={<NotFound />} />
            </Route>
            <Route path="login" element={<Login />} />
            <Route path="register" element={<Register />} />
          </Routes>
        </ThemeProvider>
      </ColorModeContext.Provider>
    </QueryClientProvider>
  );
}

额外优化建议

如果NavBar本身还会因为无关props变化触发重渲染,可以用React.memo包裹它,进一步减少不必要的渲染:

const NavBar = React.memo(() => {
  // NavBar的原有实现代码
});

内容的提问来源于stack exchange,提问作者WillowDweller

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 22:02:38