import React, { useRef } from 'react'; import { useLocation, useOutlet } from 'react-router'; const MAX_CACHED_PAGES = 30; /** * 路由保活:切换页面时保留已访问页面的组件实例(输入、滚动、弹窗状态不丢失)。 * 隐藏页面仍挂载在 DOM 中,仅通过 display:none 隐藏。 */ export const RouteKeeper: React.FC = () => { const location = useLocation(); const outlet = useOutlet(); const cacheRef = useRef>(new Map()); const orderRef = useRef([]); // 仅以 pathname 作为缓存键:页面内部通过 URL 参数同步状态时不会 // 产生第二个实例,切回时也不会因此重挂载。 const pageKey = location.pathname; if (outlet && !cacheRef.current.has(pageKey)) { cacheRef.current.set(pageKey, outlet); orderRef.current.push(pageKey); if (orderRef.current.length > MAX_CACHED_PAGES) { const oldest = orderRef.current.shift(); if (oldest && oldest !== pageKey) cacheRef.current.delete(oldest); } } return ( <> {Array.from(cacheRef.current.entries()).map(([key, node]) => (
{node}
))} ); }; export default RouteKeeper;