javascriptreactjsreact-routerreact-router-dom

react-router v6: Navigate to a URL with searchParams


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?


Solution

  • 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