import { useEffect, useState } from 'react'; /** * 把模块内子 tab 状态同步到 URL hash 二级段。 * hash 形如 `#`(= 默认 sub)或 `#/`。 * 默认值不写入 hash,刷新页面可恢复。 */ export function useHashSubTab( moduleId: string, subs: readonly T[], ): [T, (sub: T) => void] { const defaultSub = subs[0]; const parse = (): T => { const hash = window.location.hash.slice(1); const [first, second] = hash.split('/'); if (first !== moduleId) return defaultSub; if (second && (subs as readonly string[]).includes(second)) return second as T; return defaultSub; }; const [sub, setSubState] = useState(parse); useEffect(() => { const onChange = () => setSubState(parse()); window.addEventListener('hashchange', onChange); return () => window.removeEventListener('hashchange', onChange); }, [moduleId]); const setSub = (next: T) => { const { pathname, search } = window.location; const newHash = next === defaultSub ? `#${moduleId}` : `#${moduleId}/${next}`; window.history.replaceState(null, '', `${pathname}${search}${newHash}`); setSubState(next); }; return [sub, setSub]; }