diff --git a/src/providers/RouterProvider.tsx b/src/providers/RouterProvider.tsx index 2470ce3..81263b5 100644 --- a/src/providers/RouterProvider.tsx +++ b/src/providers/RouterProvider.tsx @@ -104,12 +104,7 @@ export function RouterProvider({ getSyncSnapshot('app/recentlyUsedTools', [], isValidPageList), ); - const [isLoaded, setIsLoaded] = useState(() => { - const snapshotKey = localStorage.getItem(`snapshot/${syncKey as string}`); - const snapshotVisible = localStorage.getItem(`snapshot/${visiblePagesKey as string}`); - const snapshotOrder = localStorage.getItem(`snapshot/${pageOrderKey as string}`); - return !!(snapshotKey && snapshotVisible && snapshotOrder); - }); + const [isLoaded, setIsLoaded] = useState(false); /** * 从异步存储中安全溯源初始数据 diff --git a/src/providers/__tests__/RouterProvider.test.tsx b/src/providers/__tests__/RouterProvider.test.tsx index 76fda0d..b71640f 100644 --- a/src/providers/__tests__/RouterProvider.test.tsx +++ b/src/providers/__tests__/RouterProvider.test.tsx @@ -277,6 +277,52 @@ describe('RouterProvider', () => { }); }); + it('localStorage 快照过期时,loadInitialData 完成前不应覆盖 chrome.storage', async () => { + const staleRoute = 'timestamp'; + const correctRoute = 'jsonTools'; + const defaultVisible = ['dashboard', 'timestamp', 'storageCleaner']; + const defaultOrder = ['timestamp', 'storageCleaner']; + + localStorage.setItem('snapshot/app/currentRoute', JSON.stringify(staleRoute)); + localStorage.setItem('snapshot/app/visiblePages', JSON.stringify(defaultVisible)); + localStorage.setItem('snapshot/app/pageOrder', JSON.stringify(defaultOrder)); + + const storage = new Map([ + ['app/currentRoute', correctRoute], + ['app/visiblePages', defaultVisible], + ['app/pageOrder', defaultOrder], + ['app/recentlyUsedTools', []], + ]); + + let resolveGet: () => void; + const getBlocked = new Promise((resolve) => { + resolveGet = resolve; + }); + + (storageUtil.get as any).mockImplementation(async (key: string, defaultValue: unknown) => { + await getBlocked; + return storage.get(key) ?? defaultValue; + }); + (storageUtil.set as any).mockImplementation(async (key: string, value: unknown) => { + storage.set(key, value); + }); + + render( + + + , + ); + + expect(screen.getByTestId('current-page')).toHaveTextContent(staleRoute); + expect(storageUtil.set).not.toHaveBeenCalledWith('app/currentRoute', staleRoute); + + resolveGet!(); + await waitFor(() => { + expect(screen.getByTestId('current-page')).toHaveTextContent(correctRoute); + expect(storage.get('app/currentRoute')).toBe(correctRoute); + }); + }); + it('组件卸载时不应设置 isLoaded 状态(竞态条件防护)', async () => { let resolveStorage: (value: unknown) => void; const storagePromise = new Promise((resolve) => {