React-Router-DOM v6.27中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
相关产品推荐
相关产品推荐

