我正在使用 React-Router-DOM v6.27 开发 React 应用程序。
应用程序具有登录和注册路由以及呈现应用程序组件的默认路由。应用程序组件包括一个导航栏和一个顶部栏以及一个用于在应用程序下定义的所有子路由的出口。
在应用程序内的各个路径(所有路径都是默认路径的子路径)之间导航时,我注意到导航栏在每个导航上重新渲染,导致状态丢失,在我的情况下是“折叠”状态导航栏。如何重构我的路线,使导航栏不会在每个导航上重新渲染,从而导致其丢失状态?
function App() {
const [theme, colorMode] = useMode();
const { QueryFeedback, queryClient } = useFeedbackQuery();
const Application = () => {
return (
<AuthenticatedView>
<div className="app">
<NavBar />
<div className="content">
<Topbar />
<main className="view">
<Outlet />
</main>
</div>
<QueryFeedback />
</div>
</AuthenticatedView>
);
}
return (
<QueryClientProvider client={queryClient}>
<ColorModeContext.Provider value={colorMode}>
<ThemeProvider theme={theme}>
<CssBaseline />
<Routes>
<Route path="/" element={<Application />}>
<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>
);
}
您已在另一个 React 组件中声明了
Application
组件,这是一种常见的 React 反模式。这不必要地重新声明 Application
组件,并且每次 App
渲染它时都会卸载“旧实例”并安装“新实例”`。当旧组件卸载其拥有的任何状态并进行垃圾收集时,新组件将从初始状态值开始。
将
Application
声明移至 ReactTree 之外,使其成为稳定的组件引用。
示例:
const Application = () => {
const { QueryFeedback } = useFeedbackQuery();
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 { queryClient } = useFeedbackQuery();
return (
<QueryClientProvider client={queryClient}>
<ColorModeContext.Provider value={colorMode}>
<ThemeProvider theme={theme}>
<CssBaseline />
<Routes>
<Route path="/" element={<Application />}>
<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>
);
}