如何让React-Router返回页面时记住上次访问的子路由?
实现React-Router哈希路由中Home页面记住上次子路由
嘿,这个需求挺实用的,我来给你分享两种靠谱的实现方式,都能解决从About切回Home时记住上次子路由的问题~
核心思路
本质上就是记录用户最后访问的Home子路由路径,然后修改Home根路由的默认重定向逻辑:不再固定跳转到/home/A,而是读取记录的路径,没有记录时才用默认值。
方式一:用localStorage持久化记录(刷新页面也能记住)
这种方式适合需要持久化记忆的场景,比如用户关闭浏览器再打开,回到Home页还是上次的子路由。
在Home子路由组件中记录当前路径
我们可以监听路由变化,当路径是Home下的子路由时,把路径存到localStorage:import { useLocation, useEffect } from 'react'; // 可以把这个逻辑封装在Home的父组件或者子路由的公共组件里 function HomeSubRouteWrapper({ children }) { const location = useLocation(); useEffect(() => { // 只记录/home下的有效子路由,排除/home本身 const validSubRoutes = ['/home/A', '/home/B', '/home/C']; if (validSubRoutes.includes(location.pathname)) { localStorage.setItem('lastHomeSubRoute', location.pathname); } }, [location.pathname]); return <>{children}</>; }然后在Home的子路由中使用这个包裹组件:
function Home() { return ( <div> {/* Home主导航栏 */} <HomeSubRouteWrapper> <Outlet /> {/* 渲染子路由内容 */} </HomeSubRouteWrapper> </div> ); }修改Home根路由的重定向逻辑
原来的默认重定向是固定到/home/A,现在改成读取localStorage中的记录:import { Routes, Route, Navigate, Outlet } from 'react-router-dom'; function AppRoutes() { const getDefaultHomePath = () => { const savedRoute = localStorage.getItem('lastHomeSubRoute'); // 验证保存的路径是否有效,防止无效值 const validRoutes = ['/home/A', '/home/B', '/home/C']; return validRoutes.includes(savedRoute) ? savedRoute : '/home/A'; }; return ( <Routes> <Route path="/about" element={<About />} /> <Route path="/home" element={<Home />}> {/* 动态重定向到上次记录的子路由 */} <Route index element={<Navigate to={getDefaultHomePath()} replace />} /> <Route path="A" element={<HomeA />} /> <Route path="B" element={<HomeB />} /> <Route path="C" element={<HomeC />} /> </Route> <Route path="/" element={<Navigate to="/home" replace />} /> </Routes> ); }
方式二:用React Context/状态记录(会话级,刷新回到默认)
如果不需要持久化记忆(比如用户刷新页面后希望回到默认的/home/A),可以用React的状态或Context来存储,避免操作localStorage。
创建Home路由状态Context
import { createContext, useContext, useState, useEffect } from 'react'; import { useLocation } from 'react-router-dom'; const HomeRouteContext = createContext('/home/A'); export function HomeRouteProvider({ children }) { const [lastSubRoute, setLastSubRoute] = useState('/home/A'); const location = useLocation(); useEffect(() => { const validRoutes = ['/home/A', '/home/B', '/home/C']; if (validRoutes.includes(location.pathname)) { setLastSubRoute(location.pathname); } }, [location.pathname]); return ( <HomeRouteContext.Provider value={lastSubRoute}> {children} </HomeRouteContext.Provider> ); } // 自定义hook方便使用 export function useHomeLastRoute() { return useContext(HomeRouteContext); }在路由中使用Context的值
先在App外层包裹Provider:import { HashRouter } from 'react-router-dom'; import { HomeRouteProvider } from './HomeRouteContext'; function App() { return ( <HashRouter> <HomeRouteProvider> {/* 导航栏和路由组件 */} <Navigation /> <AppRoutes /> </HomeRouteProvider> </HashRouter> ); }然后修改Home根路由的重定向:
import { useHomeLastRoute } from './HomeRouteContext'; function AppRoutes() { const lastSubRoute = useHomeLastRoute(); return ( <Routes> <Route path="/about" element={<About />} /> <Route path="/home" element={<Home />}> <Route index element={<Navigate to={lastSubRoute} replace />} /> <Route path="A" element={<HomeA />} /> <Route path="B" element={<HomeB />} /> <Route path="C" element={<HomeC />} /> </Route> <Route path="/" element={<Navigate to="/home" replace />} /> </Routes> ); }
两种方式都能完美解决你的问题,根据是否需要持久化记忆来选择就好啦~
内容的提问来源于stack exchange,提问作者Brian H.
相关产品推荐
相关产品推荐

