reactjs - NextJS: Adicionar um novo valor à string de consulta de um asPath existente ou atualizar a string de consulta existente


Estou meio perdido sobre como funciona o sistema de router do NextJS:

Tenho artigos por categorias que podem ser:

Medical
Charity
Wedding
Funeral

Estou a ter uma barra de navegação onde o utilizador pode mostrar artigos por categoria, e também pode pesquisar por uma palavra-chave. A funcionalidade de categorias está a funcionar perfeitamente.

É assim que a minha barra de navegação se parece:

Isso significa que se o utilizador clicar em All, estaremos a exibir todos os artigos:

Aqui está o cenário:

  • Quando clicamos, por exemplo, em Medical, o URL fica assim: http://localhost:3000/articles?category=medical
  • Quando clicamos em all, o URL fica como http://localhost:3000/articles
  • Quando clicamos em all e pesquisamos a palavra-chave COVID, o URL fica assim: http://localhost:3000/articles?search=covid

PROBLEMA

Agora quero combinar categorias e pesquisa: Se o utilizador clicar em medical e procurar pela palavra-chave COVID, a URL deve parecer com isto: http://localhost:3000/articles?category=medical&search=covid.

Depois de obter o resultado da pesquisa, quando o utilizador muda a palavra-chave, quero substituir a cadeia de consulta search pelo novo valor.

COMO EU TENTEI FAZER?

Eu sei que o objeto router do NextJS tem:

  • pathname: Rota atual. Ou seja, o caminho da página em /pages
  • e asPath: Caminho real (incluindo a query) mostrado no navegador
const { push, asPath } = useRouter();

const onSearchKeyPress = (e: React.KeyboardEvent<HTMLInputElement>) => {
    const keyword = e.currentTarget.value;
    if (e.key === "Enter") {
      url = !isEmpty(keyword.trim())
        ? {
          pathname: asPath,
          query: { search: keyword },
        }
        : {
          pathname,
        };
      push(url);
    }
  };

Mas fazê-lo está a codificar o asPath e a resultar nesta URL: http://localhost:3000/article%3Fcategory=covid&search=covid que está a mostrar a página 404 de não encontrado.

Então, eu nem sei se consigo substituir o search por um novo valor, já que o utilizador quer realizar uma nova pesquisa.

Resposta #1

Resolvi o problema não utilizando o asPath: em vez disso, usei o pathname juntamente com o operador spread da seguinte forma:

url = !isEmpty(keyword.trim())
     ? {
        pathname,
        query: { ...query, search: keyword },
     }: {
        pathname: page,
     };