diff --git a/packages/solid-router/tests/useMatch.test.tsx b/packages/solid-router/tests/useMatch.test.tsx index 5375f7e3b73..9de000544b7 100644 --- a/packages/solid-router/tests/useMatch.test.tsx +++ b/packages/solid-router/tests/useMatch.test.tsx @@ -118,4 +118,62 @@ describe('useMatch', () => { }) }) }) + + test('route-scoped useParams should remain readable from async work created by the route during navigation away', async () => { + let releaseDelayedRead: () => void = () => {} + const delayedReadGate = new Promise((resolve) => { + releaseDelayedRead = resolve + }) + let delayedRead!: Promise + let delayedError: unknown + + const rootRoute = createRootRoute({ + component: () => , + }) + const postRoute = createRoute({ + getParentRoute: () => rootRoute, + path: '/posts/$postId', + component: function PostComponent() { + const params = postRoute.useParams() + + delayedRead = delayedReadGate.then(() => { + try { + params() + } catch (err) { + delayedError = err + } + }) + + return

Post {params().postId}

+ }, + }) + const otherRoute = createRoute({ + getParentRoute: () => rootRoute, + path: '/other', + component: () =>

OtherTitle

, + }) + const router = createRouter({ + routeTree: rootRoute.addChildren([postRoute, otherRoute]), + history: createMemoryHistory({ initialEntries: ['/posts/one'] }), + }) + + render(() => ) + expect(await screen.findByText('Post one')).toBeInTheDocument() + + await router.navigate({ to: '/other' }) + expect(await screen.findByText('OtherTitle')).toBeInTheDocument() + + releaseDelayedRead() + await delayedRead + + if (delayedError) { + throw new Error( + `Route-scoped useParams threw after navigation away: ${ + delayedError instanceof Error + ? delayedError.message + : String(delayedError) + }`, + ) + } + }) })