Skip to content

Commit 53847bb

Browse files
jonkoopstimdorr
andcommitted
Memoize result from useMatch() between renders (#8431)
Co-authored-by: Tim Dorr <[email protected]>
1 parent 1108f1c commit 53847bb

File tree

2 files changed

+44
-2
lines changed

2 files changed

+44
-2
lines changed

packages/react-router/__tests__/useMatch-test.tsx

+42-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as React from "react";
22
import * as TestRenderer from "react-test-renderer";
3-
import { MemoryRouter, Routes, Route, useMatch } from "react-router";
3+
import { MemoryRouter, PathMatch, Routes, Route, useMatch } from "react-router";
44

55
function ShowMatch({ pattern }: { pattern: string }) {
66
return <pre>{JSON.stringify(useMatch(pattern), null, 2)}</pre>;
@@ -93,4 +93,45 @@ describe("useMatch", () => {
9393
`);
9494
});
9595
});
96+
97+
describe("when re-rendered with the same URL", () => {
98+
it("returns the memoized match", () => {
99+
let path = "/home";
100+
let match: PathMatch<string>;
101+
let firstMatch: PathMatch<string>;
102+
103+
function HomePage() {
104+
match = useMatch(path);
105+
106+
if (!firstMatch) {
107+
firstMatch = match;
108+
}
109+
110+
return null;
111+
}
112+
113+
let renderer: TestRenderer.ReactTestRenderer;
114+
TestRenderer.act(() => {
115+
renderer = TestRenderer.create(
116+
<MemoryRouter initialEntries={[path]}>
117+
<Routes>
118+
<Route path={path} element={<HomePage />} />
119+
</Routes>
120+
</MemoryRouter>
121+
);
122+
});
123+
124+
TestRenderer.act(() => {
125+
renderer.update(
126+
<MemoryRouter initialEntries={[path]}>
127+
<Routes>
128+
<Route path={path} element={<HomePage />} />
129+
</Routes>
130+
</MemoryRouter>
131+
);
132+
});
133+
134+
expect(match).toBe(firstMatch);
135+
});
136+
});
96137
});

packages/react-router/index.tsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,8 @@ export function useMatch<ParamKey extends string = string>(
431431
`useMatch() may be used only in the context of a <Router> component.`
432432
);
433433

434-
return matchPath(pattern, useLocation().pathname);
434+
let { pathname } = useLocation();
435+
return React.useMemo(() => matchPath(pattern, pathname), [pathname, pattern]);
435436
}
436437

437438
/**

0 commit comments

Comments
 (0)