You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
tl;dr: relative routing using Route.useNavigate() can result in recursive URL appending
This is difficult to explain, so I recommend to look at the repo + reproduction steps.
Here is a peace of code to illustrate the context in which the bug occures :
// Relative routing using the exported Route suggar functionsconstnavigate=Route.useNavigate()// I expect `from` to be injected inside the exported suggar functionnavigate({to: './$postId'params: {postId: 1,}})
To trigger the issue, you need to have a blocking loader (ex: loading the post detail). By clicking mulitple time on the imperative navigation (= before the loader resolves, and thus the SPA transition happen) you will result in a wron routing (ex: /posts/1/1/1/1).
The issue is fixed by explicitly injecting the from
Click multiple times on the same post "link button" (I know using a <Link /> component is better, I need to illustrate the issue with imperative navigation)
You must click multiple times rapidly enough to trigger a navigation event before the blocking loader that prevent transition resolves
In the case of data being cached, the navigation may resolve instantly
The resulting URL keep appending the relative path segment provided in to parameter.
You end up being "redirected" to an URL like /posts/2/2/2/2/2...., resulting in a 404
Expected behavior
I expect to have an "indempotent" routing behaviour (= URL will always be the same for each call to the imperative navigation, mostly like we have with <Link /> components)
I dig a litle in the source code and I discovered that exported Route.use* functions are all injecting from: this.id to "global" hooks (like useParams, useSearch, useNavigate...).
Still, in useNavigate implementation, the injected params are ignored in the implementation, is it on purpose for TS to work ? or is it a miss due to a refactor or something ? (in useSearch this is injected inside useMatch for example).
In the end, since no from is injected, the fromPath resolved to this.latestLocation.pathname (which explain why multiple clicks append multiple times the relative path segment)
Which project does this relate to?
Router
Describe the bug
tl;dr: relative routing using
Route.useNavigate()
can result in recursive URL appendingThis is difficult to explain, so I recommend to look at the repo + reproduction steps.
Here is a peace of code to illustrate the context in which the bug occures :
To trigger the issue, you need to have a blocking loader (ex: loading the post detail). By clicking mulitple time on the imperative navigation (= before the loader resolves, and thus the SPA transition happen) you will result in a wron routing (ex:
/posts/1/1/1/1
).The issue is fixed by explicitly injecting the
from
Your Example Website or App
https://stackblitz.com/edit/github-wyacx2ti?file=src%2Froutes%2Findex.tsx,src%2Froutes%2F__root.tsx,src%2Froutes%2Fposts.tsx,src%2Froutes%2Fposts.index.tsx,src%2Froutes%2Fposts.%24postId.tsx
Steps to Reproduce the Bug or Issue
/posts
list page<Link />
component is better, I need to illustrate the issue with imperative navigation)to
parameter./posts/2/2/2/2/2....
, resulting in a 404Expected behavior
I expect to have an "indempotent" routing behaviour (= URL will always be the same for each call to the imperative navigation, mostly like we have with
<Link />
components)I dig a litle in the source code and I discovered that exported
Route.use*
functions are all injectingfrom: this.id
to "global" hooks (likeuseParams
,useSearch
,useNavigate
...).Still, in
useNavigate
implementation, the injected params are ignored in the implementation, is it on purpose for TS to work ? or is it a miss due to a refactor or something ? (inuseSearch
this is injected insideuseMatch
for example).router/packages/react-router/src/useNavigate.tsx
Lines 17 to 33 in 7d76812
In the end, since no
from
is injected, thefromPath
resolved tothis.latestLocation.pathname
(which explain why multiple clicks append multiple times the relative path segment)router/packages/react-router/src/router.ts
Lines 1455 to 1478 in 7d76812
Screenshots or Videos
Screen.Recording.2025-02-14.at.15.36.29.mov
Platform
Additional context
No response
The text was updated successfully, but these errors were encountered: