Skip to content

Commit b8165ab

Browse files
fix(react-router): fix path param handling with relative navigation (#3423)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
1 parent 2a83af7 commit b8165ab

File tree

2 files changed

+63
-1
lines changed

2 files changed

+63
-1
lines changed

packages/react-router/src/router.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1491,7 +1491,9 @@ export class Router<
14911491
)
14921492
let pathname: string
14931493
if (dest.to) {
1494-
pathname = this.resolvePathWithBase(fromPath, `${dest.to}`)
1494+
const resolvePathTo =
1495+
fromMatch?.fullPath || this.latestLocation.pathname
1496+
pathname = this.resolvePathWithBase(resolvePathTo, `${dest.to}`)
14951497
} else {
14961498
const fromRouteByFromPathRouteId =
14971499
this.routesById[

packages/react-router/tests/navigate.test.tsx

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,3 +488,63 @@ describe('router.navigate navigation using layout routes resolves correctly', ()
488488
expect(router.state.location.search).toStrictEqual({ 'foo=bar': 3 })
489489
})
490490
})
491+
492+
describe('relative navigation', () => {
493+
it('should navigate to a child route', async () => {
494+
const { router } = createTestRouter(
495+
createMemoryHistory({ initialEntries: ['/posts'] }),
496+
)
497+
498+
await router.load()
499+
500+
expect(router.state.location.pathname).toBe('/posts')
501+
502+
await router.navigate({
503+
from: '/posts',
504+
to: './$slug',
505+
params: { slug: 'tkdodo' },
506+
})
507+
508+
await router.invalidate()
509+
510+
expect(router.state.location.pathname).toBe('/posts/tkdodo')
511+
})
512+
513+
it('should navigate to a parent route', async () => {
514+
const { router } = createTestRouter(
515+
createMemoryHistory({ initialEntries: ['/posts/tanner'] }),
516+
)
517+
518+
await router.load()
519+
520+
expect(router.state.location.pathname).toBe('/posts/tanner')
521+
522+
await router.navigate({
523+
to: '..',
524+
})
525+
526+
await router.invalidate()
527+
528+
expect(router.state.location.pathname).toBe('/posts')
529+
})
530+
531+
it('should navigate to a sibling route', async () => {
532+
const { router } = createTestRouter(
533+
createMemoryHistory({ initialEntries: ['/posts/tanner'] }),
534+
)
535+
536+
await router.load()
537+
538+
expect(router.state.location.pathname).toBe('/posts/tanner')
539+
540+
await router.navigate({
541+
from: '/posts/$slug',
542+
to: '.',
543+
params: { slug: 'tkdodo' },
544+
})
545+
546+
await router.invalidate()
547+
548+
expect(router.state.location.pathname).toBe('/posts/tkdodo')
549+
})
550+
})

0 commit comments

Comments
 (0)