Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

298
Visualizações
How to combine react-router-dom's setSearchParams with route that has a param in a way that allows correct back button usage?

I have a set of routes that look like this:

{
    path: '/things',
    element: <MainLayout />,
    children: [
        {
            path: 'search',
            element: <MainSearch />,
        },
        {
            path: 'search/:thingId',
            element: <ThingLayout />,
        },
        {
            path: '',
            element: <Navigate to="search" replace />,
        },
    ],
},

Wherein the idea is you search for something on MainSearch, are given results, click it, and are brought to a page /things/search/:thingId for that Thing.

However, ThingLayout has a tab paradigm happening too, which is set by search params, and the user clicking tabs within that component.

ThingLayout.tsx

import { useParams, useSearchParams } from 'react-router-dom';

const ThingLayout = () => {
    const [searchParams, setSearchParams] = useSearchParams();
    const activeTab = searchParams.get('tab');

    // When the user first comes here from general search route, 
    // set the default tab
    useEffect(() => {
        if (!activeTab) {
            setSearchParams({ tab: DEFAULT_TAB });
        }
    }, []);

// ...
}

My trouble is, I need (I believe) the generalized /search/:thingId route so that all my various /search/:thingId?tab=someTab routes resolve to this component, which then has code to check which tab is set via searchParams and then render the proper child component, but if a user presses the back button, the URL changes to /search/:thingId and then immediately back to /search/:thingId?tab=defaultTab. I tried using navigate rather than setSearchParams to change the URL:

import { useNavigate } from 'react-router-dom';

// ...
    const navigate = useNavigate();
    navigate(`?tab=${DEFAULT_INVENTORY_PARTS_TAB}`)

But I had the same issue: when coming from search, first the URL would be /search/:thingId, then it would become ?tab=defaultTab.

I've searched through the react router docs, as well as looked at a great many stackoverflow questions, and I'm thinking now maybe I just am following a bad pattern? Is my method of tab navigation compatible with the "right" way to use React Router? How can I combine the general :id route with my manipulated searchParams route?

My react router version is "react-router-dom": "^6.2.1"

about 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

The setSearchParams works similar to the navigate function but only for the URL queryString. It takes an options object that is the same type argument as navigate.

declare function useSearchParams(
  defaultInit?: URLSearchParamsInit
): [URLSearchParams, SetURLSearchParams];

type ParamKeyValuePair = [string, string];

type URLSearchParamsInit =
  | string
  | ParamKeyValuePair[]
  | Record<string, string | string[]>
  | URLSearchParams;

type SetURLSearchParams = (
  nextInit?: URLSearchParamsInit,
  navigateOpts?: : { replace?: boolean; state?: any }
) => void;

Pass a navigateOpts object that sets the navigation type to be a redirect.

import { useParams, useSearchParams } from 'react-router-dom';

const ThingLayout = () => {
  const [searchParams, setSearchParams] = useSearchParams();
  const activeTab = searchParams.get('tab');

  // When the user first comes here from general search route, 
  // set the default tab
  useEffect(() => {
    if (!activeTab) {
      searchParams.set("tab", DEFAULT_TAB);
      setSearchParams(searchParams, { replace: true });
    }
  }, []);

  // ...
}
about 4 years ago · Santiago Trujillo Relatório

0

The answer is to use the navigate function provided by react-router-dom's useNavigate hook, which has a replace parameter that can be passed to it, to replace the current item in history.

So my code that checks to see if there is a tab selected, and if not, sets the search parameter, now navigates to the URL with the proper search parameter set, rather than setting the search parameter directly and only.

import { useParams, useSearchParams } from 'react-router-dom';

const ThingLayout = () => {
    const [searchParams, setSearchParams] = useSearchParams();
    const activeTab = searchParams.get('tab');

    // When the user first comes here from general search route, 
    // set the default tab
    useEffect(() => {
        if (!activeTab) {
            setSearchParams({ tab: DEFAULT_TAB });
        }
    }, []);

// ...
}

becomes

import { useSearchParams, useNavigate } from 'react-router-dom';

const ThingLayout = () => {
    const [searchParams] = useSearchParams();
    const navigate = useNavigate();
    const activeTab = searchParams.get('tab');

    // When the user first comes here from general search route, 
    // set the default tab
    useEffect(() => {
        if (!activeTab) {
            navigate(`?tab=${DEFAULT_TAB}`, {replace: true});
        }
    }, []);

// ...
}
about 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda