diff --git a/web/src/App.tsx b/web/src/App.tsx index 09f4f505..b957e226 100644 --- a/web/src/App.tsx +++ b/web/src/App.tsx @@ -790,32 +790,44 @@ export default function App() { }, [activeSessionId]); // 监听 URL 哈希 (#/s/{sessionId}/m/{messageId}) 实现深链接直接定位与脉冲动效 + const activeSessionIdRef = useRef(activeSessionId); + useEffect(() => { + activeSessionIdRef.current = activeSessionId; + }, [activeSessionId]); + + const loadDayForAnchorRef = useRef(chatWindow.loadDayForAnchor); + useEffect(() => { + loadDayForAnchorRef.current = chatWindow.loadDayForAnchor; + }, [chatWindow.loadDayForAnchor]); + useEffect(() => { const handleHashChange = () => { const parsed = parseAnchorHash(window.location.hash); if (!parsed) return; - if (parsed.sessionId && parsed.sessionId !== activeSessionId) { + const currentActive = activeSessionIdRef.current; + if (parsed.sessionId && parsed.sessionId !== currentActive) { setActiveSessionId(parsed.sessionId); setTimeout(() => { navigateToAnchor(parsed, { sessionId: parsed.sessionId, - loadDayForAnchor: chatWindow.loadDayForAnchor, + loadDayForAnchor: loadDayForAnchorRef.current, }); }, 300); } else { navigateToAnchor(parsed, { - sessionId: activeSessionId, - loadDayForAnchor: chatWindow.loadDayForAnchor, + sessionId: currentActive, + loadDayForAnchor: loadDayForAnchorRef.current, }); } }; window.addEventListener('hashchange', handleHashChange); + // 仅在初始页面加载时检查一次 URL hash if (window.location.hash) { handleHashChange(); } return () => window.removeEventListener('hashchange', handleHashChange); - }, [activeSessionId, chatWindow.loadDayForAnchor]); + }, []); // 仅在挂载时监听 hashchange,避免 activeSessionId 变更时因残留 hash 产生回弹 // 引用消息交互 const handleQuoteMessage = (message: ChatMessage) => { @@ -1866,7 +1878,13 @@ export default function App() { { + // 切换项目时清理旧会话的残留锚点 hash,防止回弹 + if (window.location.hash) { + history.replaceState(null, '', window.location.pathname + window.location.search); + } + setActiveSessionId(sessId); + }} onNewSession={() => { const newSessId = 'sess-' + Date.now(); const newProjId = Date.now();