Skip to content

Commit

Permalink
Fix useMatch undecoded params (#11789)
Browse files Browse the repository at this point in the history
  • Loading branch information
brophdawg11 authored Jul 10, 2024
1 parent 03d6cf2 commit da65120
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .changeset/big-trainers-cough.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"react-router": patch
---

Fix regression and properly decode paths inside `useMatch` so matches/params reflect decoded params
47 changes: 47 additions & 0 deletions packages/react-router-dom/__tests__/special-characters-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
HashRouter,
MemoryRouter,
Link,
Outlet,
Routes,
Route,
RouterProvider,
Expand All @@ -23,6 +24,7 @@ import {
createMemoryRouter,
createRoutesFromElements,
useLocation,
useMatch,
useNavigate,
useParams,
} from "react-router-dom";
Expand Down Expand Up @@ -962,6 +964,51 @@ describe("special character tests", () => {
`"<pre>{"pathname":"/with%20space","search":"","hash":""}</pre>"`
);
});

it("properly decodes params in useMatch", () => {
let testWindow = getWindow("/user/bücherwurm");

let router = createBrowserRouter(
[
{
path: "/",
Component() {
let match = useMatch("/user/:username");
return (
<>
<pre>{JSON.stringify(match, null, 2)}</pre>
<Outlet />
</>
);
},
children: [
{
path: "user/:username",
element: null,
},
],
},
],
{ window: testWindow }
);
let ctx = render(<RouterProvider router={router} />);

expect(testWindow.location.pathname).toBe("/user/b%C3%BCcherwurm");
expect(ctx.container.innerHTML).toMatchInlineSnapshot(`
"<pre>{
"params": {
"username": "bücherwurm"
},
"pathname": "/user/bücherwurm",
"pathnameBase": "/user/bücherwurm",
"pattern": {
"path": "/user/:username",
"caseSensitive": false,
"end": true
}
}</pre>"
`);
});
});

describe("hash routers", () => {
Expand Down
3 changes: 2 additions & 1 deletion packages/react-router/lib/hooks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
IDLE_BLOCKER,
Action as NavigationType,
UNSAFE_convertRouteMatchToUiMatch as convertRouteMatchToUiMatch,
UNSAFE_decodePath as decodePath,
UNSAFE_getResolveToMatches as getResolveToMatches,
UNSAFE_invariant as invariant,
isRouteErrorResponse,
Expand Down Expand Up @@ -141,7 +142,7 @@ export function useMatch<

let { pathname } = useLocation();
return React.useMemo(
() => matchPath<ParamKey, Path>(pattern, pathname),
() => matchPath<ParamKey, Path>(pattern, decodePath(pathname)),
[pathname, pattern]
);
}
Expand Down
1 change: 1 addition & 0 deletions packages/router/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ export {
ErrorResponseImpl as UNSAFE_ErrorResponseImpl,
convertRoutesToDataRoutes as UNSAFE_convertRoutesToDataRoutes,
convertRouteMatchToUiMatch as UNSAFE_convertRouteMatchToUiMatch,
decodePath as UNSAFE_decodePath,
getResolveToMatches as UNSAFE_getResolveToMatches,
} from "./utils";

Expand Down
2 changes: 1 addition & 1 deletion packages/router/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1075,7 +1075,7 @@ function compilePath(
return [matcher, params];
}

function decodePath(value: string) {
export function decodePath(value: string) {
try {
return value
.split("/")
Expand Down

0 comments on commit da65120

Please sign in to comment.