Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 778
caseyjhol Avatar asked Jan 19 '21 22:01

caseyjhol


2 Answers

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

like image 81
caseyjhol Avatar answered Oct 21 '22 18:10

caseyjhol


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.

Demo - POC

Edit react-router-v6-navigate-to-a-url-with-searchparams

like image 29
Drew Reese Avatar answered Oct 21 '22 19:10

Drew Reese