Skip to content

Commit

Permalink
useParams() should remove unused keys.
Browse files Browse the repository at this point in the history
  • Loading branch information
molefrog committed Jan 30, 2025
1 parent e165511 commit 7e6b4d6
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 7 deletions.
16 changes: 9 additions & 7 deletions packages/wouter/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -195,14 +195,16 @@ const h_route = ({ children, component }, params) => {
return typeof children === "function" ? children(params) : children;
};

// a hook to cache the params object between renders (if they are shallow equal)
// Cache params object between renders if values are shallow equal
const useCachedParams = (value) => {
let prev = useRef(Params0),
curr = prev.current;

for (const k in value) if (value[k] !== curr[k]) curr = value;
if (Object.keys(value).length === 0) curr = value;
return (prev.current = curr);
let prev = useRef(Params0);
const curr = prev.current;
return (prev.current =
// Update cache if number of params changed or any value changed
Object.keys(value).length !== Object.keys(curr).length ||
Object.entries(value).some(([k, v]) => v !== curr[k])
? value // Return new value if there are changes
: curr); // Return cached value if nothing changed
};

export function useSearchParams() {
Expand Down
38 changes: 38 additions & 0 deletions packages/wouter/test/use-params.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -183,3 +183,41 @@ it("makes the params an empty object, when there are no path params", () => {
act(() => navigate("/posts"));
expect(Object.keys(result.current).length).toBe(0);
});

it("removes route parameters when no longer present in the path", () => {
// Start at a route that has both 'category' and 'page' in its params
const { hook, navigate } = memoryLocation({
path: "/products/categories/apple/page/1",
});

// Render useParams within two routes: one with /page/:page, one without
const { result } = renderHook(() => useParams(), {
wrapper: (props) => (
<Router hook={hook}>
<Switch>
<Route path="/products/categories/:category">{props.children}</Route>
<Route path="/products/categories/:category/page/:page">
{props.children}
</Route>
</Switch>
</Router>
),
});

// Initial params should include 'category' and 'page'
expect(result.current).toMatchObject({
0: "apple",
1: "1",
category: "apple",
page: "1",
});

// Navigate to a path that no longer contains the page param
act(() => navigate("/products/categories/apple"));

// The 'page' param should now be removed
expect(result.current).toEqual({
0: "apple",
category: "apple",
});
});

0 comments on commit 7e6b4d6

Please sign in to comment.