T
TanStack17mo ago
raw-harlequin

How do you clear search params from URL upon navigating from one page to another?

I have a page which can have search params in the URL for filtering the items on that page (things such as page and pageSize). From this page I can click on one of the items to navigate me to a totally different page under a different route path (the page im navigating to isnt a child route of the page im navigating from). The issue is that any search params in the URL before navigating persist to the page I am navigating to. I have tried using the useNavigate hook to navigate to the new page upon a button click and setting the search params to empty strings
function handleClick() {
navigate({
to: "/destinationRoute",
search: {page: "", pageSize: ""},
});
}
function handleClick() {
navigate({
to: "/destinationRoute",
search: {page: "", pageSize: ""},
});
}
I have also tried something similar using the Link component but havent had success with that either. Is there quick and clean way to clear search params? I've tried scanning through the docs but haven't seen much for this specific use case maybe im missing something. Thank you! https://tanstack.com/router/latest/docs/framework/react/guide/search-params
Search Params | TanStack Router React Docs
Similar to how TanStack Query made handling server-state in your React applications a breeze, TanStack Router aims to unlock the power of URL search params in your applications. Why not just use URLSearchParams?
6 Replies
intermediate-olive
intermediate-olive17mo ago
Have you tried passing search: undefined or false?
raw-harlequin
raw-harlequinOP17mo ago
Hey Sean, I actually just now figured out the issue. I have some default search params (page and pageSize) I wanted to set on the page that has filtering options, so I did that in the beforeLoad function of the route and then used the useNavigate hook to update the URL with the default search params (probably not best practice). The issue was that I didn't wrap the useNavigate in a useEffect so when I navigated away from the page it caused some weird rendering issues and the destination page would render twice (once with no search params and then with search params persisted). This is pretty much the code I had previously, now I wrapped the navigate call in a useEffect and the navigating to the destination page works as expected.
// Route
const searchParamsSchema = z.object({
page: z.number().optional(),
pageSize: z.number().optional(),
});

export const Route = createFileRoute("/pageWithFilterOptions")({
component: PageWithFilterOptions,
beforeLoad: async ({ search }) => {
if (!search.page) {
search.page = 1;
}
if (!search.pageSize) {
search.pageSize = 20;
}
},
validateSearch: searchParamsSchema,
});
// Route
const searchParamsSchema = z.object({
page: z.number().optional(),
pageSize: z.number().optional(),
});

export const Route = createFileRoute("/pageWithFilterOptions")({
component: PageWithFilterOptions,
beforeLoad: async ({ search }) => {
if (!search.page) {
search.page = 1;
}
if (!search.pageSize) {
search.pageSize = 20;
}
},
validateSearch: searchParamsSchema,
});
// Route component
export function PageWithFilterOptions() {
const routeApi = getRouteApi("/pageWithFilterOptions");
const { page, pageSize } = routeApi.useSearch();
const navigate = useNavigate({ from: "/pageWithFilterOptions" });
navigate({
search: (prev) => ({
...prev,
pageSize: pageSize,
displayName: displayName,
}),
});
}
// Route component
export function PageWithFilterOptions() {
const routeApi = getRouteApi("/pageWithFilterOptions");
const { page, pageSize } = routeApi.useSearch();
const navigate = useNavigate({ from: "/pageWithFilterOptions" });
navigate({
search: (prev) => ({
...prev,
pageSize: pageSize,
displayName: displayName,
}),
});
}
intermediate-olive
intermediate-olive17mo ago
Ahhhh, ok ok. Btw, you can move the getRouteApi call outside of the component scope and increase perf abit since, it can be made stable.
raw-harlequin
raw-harlequinOP17mo ago
Thanks, ill try that out! Also, would this be the appropriate way to achieve the goal of setting default search params for a route? I noticed that when I navigate to this page pushes 2 things to the browser history (the route with no search params and the route with default search params after the useNavigate pushes it to the URL)
intermediate-olive
intermediate-olive17mo ago
I tend to add em using the validateSearch parser or even using the preSearchFilters prop. Like here for preSearchFilters: https://github.com/SeanCassiere/nv-rental-clone/blob/24cb40179cd06817e700a33a92d7d7364032f74c/src/routes/_auth/(agreements)/agreements.index.tsx#L69-L75
GitHub
nv-rental-clone/src/routes/_auth/(agreements)/agreements.index.tsx ...
Navotar with Tailwind and the Tanstack. Contribute to SeanCassiere/nv-rental-clone development by creating an account on GitHub.
raw-harlequin
raw-harlequinOP17mo ago
Thanks! I tried it out but couldnt quite wrap my head around it. I ended up just setting default values in the schema created with zod and that seems to work.
const searchParamsSchema = z.object({
page: z.number().default(1),
pageSize: z.number().default(4),
});

export const Route = createFileRoute("/pageWithFilterOptions")({
component: PageWithFilterOptions,
validateSearch: searchParamsSchema,
});
const searchParamsSchema = z.object({
page: z.number().default(1),
pageSize: z.number().default(4),
});

export const Route = createFileRoute("/pageWithFilterOptions")({
component: PageWithFilterOptions,
validateSearch: searchParamsSchema,
});
I guess the question im left with is: Is there a way to reflect the default query params in the URL without a rerender with useNavigate at the component level? I dont mind not displaying the default searchParams like page and pageSize in the URL on the initial load of the page but if its possible id prefer to show them.

Did you find this page helpful?