Skip to content

Commit ab6f27b

Browse files
committed
rersolve inconsistency between solid and react implementation
1 parent 41481f7 commit ab6f27b

File tree

6 files changed

+71
-72
lines changed

6 files changed

+71
-72
lines changed

packages/react-router/src/link.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,17 +99,18 @@ export function useLinkProps<
9999
structuralSharing: true as any,
100100
})
101101

102-
const { getFromPath } = useActiveLocation()
102+
const { getFromPath, activeLocation } = useActiveLocation()
103103

104-
const from = getFromPath(options.from)
104+
const from = getFromPath(options.from);
105105

106106
const _options = React.useMemo(
107107
() => {
108-
return { ...options, from }
108+
return { ...options, from }
109109
},
110110
// eslint-disable-next-line react-hooks/exhaustive-deps
111111
[
112112
router,
113+
activeLocation,
113114
currentSearch,
114115
from,
115116
options._fromLocation,
Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,47 @@
11
import { last } from '@tanstack/router-core'
2+
import { useCallback, useEffect, useState } from 'react'
23
import { useRouter } from './useRouter'
34
import { useMatch } from './useMatch'
4-
import { useRouterState } from './useRouterState'
5-
import type { AnyRouteMatch } from '@tanstack/router-core'
5+
import type { AnyRouteMatch, ParsedLocation } from '@tanstack/router-core'
66

77
export type UseLocationResult = {
88
activeLocationMatch: AnyRouteMatch | undefined
99
getFromPath: (from?: string) => string
1010
}
1111

12-
export const useActiveLocation = (): UseLocationResult => {
13-
const router = useRouter()
12+
export const useActiveLocation = (location?: ParsedLocation) => {
13+
const {matchRoutes, state} = useRouter()
14+
const [activeLocation, setActiveLocation] = useState<ParsedLocation>(location ?? state.location)
15+
const [customActiveLocation, _setCustomActiveLocation] = useState<ParsedLocation>(location ?? state.location)
16+
const [useCustomActiveLocation, setUseCustomActiveLocation] = useState(!!location)
17+
18+
useEffect(() => {
19+
if (!useCustomActiveLocation) {
20+
setActiveLocation(state.location)
21+
} else {
22+
setActiveLocation(customActiveLocation)
23+
}
24+
}, [state.location, useCustomActiveLocation, customActiveLocation])
25+
26+
const setCustomActiveLocation = (location: ParsedLocation) => {
27+
_setCustomActiveLocation(location);
28+
setUseCustomActiveLocation(true);
29+
}
1430

1531
const currentRouteMatch = useMatch({
1632
strict: false,
1733
select: (match) => match,
1834
})
1935

20-
const activeLocation = useRouterState({
21-
select: (s) => s.location,
22-
structuralSharing: true as any,
23-
})
36+
const getFromPath = useCallback((from?: string) => {
37+
const activeLocationMatches = matchRoutes(activeLocation, {
38+
_buildLocation: false,
39+
})
2440

25-
const activeLocationMatches = router.matchRoutes(activeLocation, {
26-
_buildLocation: false,
27-
})
41+
const activeLocationMatch = last(activeLocationMatches)
2842

29-
const activeLocationMatch = last(activeLocationMatches)
30-
31-
const getFromPath = (from?: string) => {
3243
return from ?? activeLocationMatch?.fullPath ?? currentRouteMatch.fullPath
33-
}
44+
}, [activeLocation, currentRouteMatch.fullPath, matchRoutes])
3445

35-
return { activeLocationMatch, getFromPath }
46+
return { activeLocation, getFromPath, setActiveLocation: setCustomActiveLocation }
3647
}

packages/react-router/src/useNavigate.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export function useNavigate<
1717
}): UseNavigateResult<TDefaultFrom> {
1818
const router = useRouter()
1919

20-
const { getFromPath, activeLocationMatch } = useActiveLocation()
20+
const { getFromPath, activeLocation } = useActiveLocation()
2121

2222
return React.useCallback(
2323
(options: NavigateOptions) => {
@@ -29,7 +29,7 @@ export function useNavigate<
2929
})
3030
},
3131
// eslint-disable-next-line react-hooks/exhaustive-deps
32-
[_defaultOpts?.from, router, activeLocationMatch],
32+
[_defaultOpts?.from, router, getFromPath, activeLocation],
3333
) as UseNavigateResult<TDefaultFrom>
3434
}
3535

packages/solid-router/src/link.tsx

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ import {
1010
removeTrailingSlash,
1111
} from '@tanstack/router-core'
1212
import { Dynamic } from 'solid-js/web'
13-
import { useActiveLocation } from './useActiveLocation'
1413
import { useRouterState } from './useRouterState'
1514
import { useRouter } from './useRouter'
1615

1716
import { useIntersectionObserver } from './utils'
1817

18+
import { useActiveLocation } from './useActiveLocation'
1919
import type {
2020
AnyRouter,
2121
Constrain,
@@ -130,17 +130,11 @@ export function useLinkProps<
130130
}
131131

132132
const currentSearch = useRouterState({
133-
select: (s) => s.location.searchStr,
133+
select: (s) => s.location.searchStr
134134
})
135135

136-
// when `from` is not supplied, use the route of the current match as the `from` location
137-
// so relative routing works as expected
138-
// const from = useMatch({
139-
// strict: false,
140-
// select: (match) => options.from ?? match.fullPath,
141-
// })
136+
const {getFromPath, activeLocation} = useActiveLocation()
142137

143-
const { getFromPath } = useActiveLocation()
144138
const from = getFromPath(options.from)
145139

146140
const _options = () => {
@@ -152,7 +146,7 @@ export function useLinkProps<
152146

153147
const next = Solid.createMemo(() => {
154148
currentSearch()
155-
from()
149+
activeLocation()
156150
return router.buildLocation(_options() as any)
157151
})
158152

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,44 @@
11
import { last } from '@tanstack/router-core'
2-
import { createMemo } from 'solid-js'
3-
import { useRouterState } from './useRouterState'
2+
import { createEffect, createSignal, } from 'solid-js'
3+
import * as Solid from 'solid-js'
44
import { useMatch } from './useMatch'
55
import { useRouter } from './useRouter'
6-
import type { Accessor } from 'solid-js'
7-
import type { AnyRouteMatch } from '@tanstack/router-core'
8-
9-
export type UseActiveLocationResult = {
10-
activeLocationMatch: Accessor<AnyRouteMatch | undefined>
11-
getFromPath: (from?: string) => Accessor<string>
12-
}
6+
import type { ParsedLocation} from '@tanstack/router-core'
7+
import { useRouterState } from './useRouterState'
138

14-
export function useActiveLocation(): UseActiveLocationResult {
9+
export function useActiveLocation(location?: ParsedLocation) {
1510
const router = useRouter()
16-
17-
const currentRouteMatch = useMatch({
18-
strict: false,
19-
select: (match) => match,
11+
const [activeLocation, setActiveLocation] = createSignal<ParsedLocation>(location ?? useRouterState({select: (state) => state.location})());
12+
const [customActiveLocation, _setCustomActiveLocation] = createSignal<ParsedLocation>(location ?? useRouterState({select: (state) => state.location})());
13+
const [useCustomActiveLocation, setUseCustomActiveLocation] = createSignal(!!location);
14+
15+
createEffect(() => {
16+
if (!useCustomActiveLocation()) {
17+
setActiveLocation(useRouterState({select: (state) => state.location}))
18+
} else {
19+
setActiveLocation(customActiveLocation())
20+
}
2021
})
2122

22-
const activeLocation = useRouterState({
23-
select: (s) => s.location,
23+
const setCustomActiveLocation = (location: ParsedLocation) => {
24+
_setCustomActiveLocation(location)
25+
setUseCustomActiveLocation(true)
26+
}
27+
28+
const matchIndex = useMatch({
29+
strict: false,
30+
select: (match) => match.index,
2431
})
2532

26-
const activeLocationMatch = createMemo(() => {
27-
const activeLocationMatches = router.matchRoutes(activeLocation(), {
33+
const getFromPath = (from?: string) => Solid.createMemo(() => {
34+
const currentRouteMatches = router.matchRoutes(activeLocation(), {
2835
_buildLocation: false,
2936
})
3037

31-
return last(activeLocationMatches)
38+
return from ??
39+
last(currentRouteMatches)?.fullPath ??
40+
router.state.matches[matchIndex()]!.fullPath
3241
})
3342

34-
const getFromPath = (from?: string) => {
35-
return createMemo(
36-
() =>
37-
from ?? activeLocationMatch()?.fullPath ?? currentRouteMatch().fullPath,
38-
)
39-
}
40-
41-
return { activeLocationMatch, getFromPath }
43+
return { activeLocation, getFromPath, setActiveLocation: setCustomActiveLocation }
4244
}

packages/solid-router/src/useNavigate.tsx

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import * as Solid from 'solid-js'
2-
import { last } from '@tanstack/router-core'
32
import { useRouter } from './useRouter'
4-
import { useMatch } from './useMatch'
3+
import { useActiveLocation } from './useActiveLocation'
54
import type {
65
AnyRouter,
76
FromPathOption,
@@ -18,23 +17,15 @@ export function useNavigate<
1817
}): UseNavigateResult<TDefaultFrom> {
1918
const router = useRouter()
2019

21-
const matchIndex = useMatch({
22-
strict: false,
23-
select: (match) => match.index,
24-
})
20+
const {getFromPath, setActiveLocation} = useActiveLocation(router.latestLocation);
2521

2622
return ((options: NavigateOptions) => {
27-
const currentRouteMatches = router.matchRoutes(router.latestLocation, {
28-
_buildLocation: false,
29-
})
23+
setActiveLocation(router.latestLocation)
24+
const from = getFromPath(options.from ?? _defaultOpts?.from)
3025

3126
return router.navigate({
3227
...options,
33-
from:
34-
options.from ??
35-
_defaultOpts?.from ??
36-
last(currentRouteMatches)?.fullPath ??
37-
router.state.matches[matchIndex()]!.fullPath,
28+
from: from()
3829
})
3930
}) as UseNavigateResult<TDefaultFrom>
4031
}

0 commit comments

Comments
 (0)