I'm using react-router v6. I want to navigate to a URL that has searchParams, but I'm not seeing a way to do this out of the box. useNavigate
allows me to navigate to a URL by passing in a string. useSearchParams
allows me to set searchParams on the current page.
I could generate the searchParams using createSearchParams
and then convert it to a string and append it to the end of the URL with a ?
in between, but that seems like a hack.
I'd like to be able to do something like:
const navigate = useNavigate();
// listing?foo=bar
navigate("listing", {
params: {
foo: "bar"
}
});
My hacky workaround:
function useNavigateParams() {
const navigate = useNavigate();
return (url: string, params: Record<string, string | string[]>) => {
const searchParams = createSearchParams(params).toString();
navigate(url + "?" + searchParams);
};
}
const navigateParams = useNavigateParams();
navigateParams("listing", {
foo: "bar"
});
Did I miss something from the documentation?
Update
It's no longer necessary to prepend ?
to search (as of ~September 2021):
import { createSearchParams, useNavigate } from "react-router-dom";
...
const navigate = useNavigate();
navigate({
pathname: "listing",
search: createSearchParams({
foo: "bar"
}).toString()
});
This isn't quite as simplified as I'd like, but I think it's the closest we can get currently. navigate
does support passing in a search query string (not an object).
import { createSearchParams, useNavigate } from "react-router-dom";
...
const navigate = useNavigate();
navigate({
pathname: "listing",
search: `?${createSearchParams({
foo: "bar"
})}`
});
Source: https://github.com/ReactTraining/react-router/issues/7743#issuecomment-770296462
What you have is looks fine to me. Using the generatePath utility it may be a little cleaner, but it is still the same basic idea.
import { generatePath, useNavigate } from "react-router-dom";
...
const useNavigateParams = () => {
const navigate = useNavigate();
return (url: string, params: Record<string, string | string[]>) => {
const path = generatePath(":url?:queryString", {
url,
queryString: createSearchParams(params).toString()
});
navigate(path);
};
};
If you think about it this isn't much of a hack, the URL needs to be defined somewhere, whether it's the path params or part of the query string, you still need to provide that detail and build a path string to navigate to.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With