C

O poder da URL como state

20 de ago. de 2024

Com o passar dos anos, as aplicações web se tornaram cada vez mais interativas, e controlar o estado delas virou algo essencial. Frameworks como React, Vue e Angular ganharam popularidade porque facilitam a gestão de estados complexos. Um simples useState, por exemplo, já nos dá total controle sobre o estado da aplicação. Mas hoje, não vou falar sobre useState ou qualquer outra solução que venha de um framework. Quero focar em um dos principais pilares da web, que sempre esteve presente em todas as mudanças e continuará sendo essencial no futuro: a URL!

Para exemplificar o uso da URL como state de uma aplicação irei abordar exemplos utilizando o react, porém a ideia central pode ser aplicada com qualquer outro framework/lib ou usando apenas JS.

Sem mais delonga, vamos ao que interessa!

Você acabou de receber uma tarefa em que é necessário construir uma página com os seguintes requisitos:

Listagem com filtros

Ao analisar a imagem e os requisitos da tarefa, identificamos a necessidade de pelo menos três estados apenas para controlar o que será exibido na tela. São eles:

Até aqui nenhum problema… Podemos simplesmente definir 3 useStates e vida que segue:

export function HomePage() {
  const [stock, setStock] = useState();
  const [category, setCategory] = useState();
  const [search, setSearch] = useState();

  ...
}

Sua tarefa foi finalizada, porém surgiu a necessidade de persistir os dados ao atualizar a página. Para resolver esse problema, você decide salvar as informações dos filtros no localStorage, garantindo a persistência dos dados mesmo quando a página for atualizada.

export function HomePage() {
  const [stock, setStock] = useState(getAndParseFromLocalStorage("stock"));
  const [category, setCategory] = useState(getAndParseFromLocalStorage("category"));
  const [search, setSearch] = useState(getAndParseFromLocalStorage("search"));

  function getAndParseFromLocalStorage(key: string) {
    const data = localStorage.getItem(key);

    if(!data) return null;

    return JSON.parse(data);
  }
  ...
}

Algumas semanas se passaram e, além de persistir os dados ao atualizar a tela, o cliente reportou que, ao aplicar o filtro e enviar o link da tela para seus colegas de trabalho, o filtro precisa ser refeito. Isso é ruim, pois seria muito mais prático compartilhar exatamente a mesma visão que ele teve ao aplicar os filtros, como acontece quando ele pesquisa no Google e envia o link para alguém.

Uma pesquisa no google por vídeos com duração de 4-20 minutos sobre o que é uma URL

Ao acessar essa URL acima você vai ter acesso a mesma pesquisa que eu ou que qualquer outra pessoa.

Você já deve ter entendido que para resolver esse e os outros problemas citados anteriormentes podemos usar o poder da URL.

Persistindo dados na URL

Antes de prosseguir é importante entender sobre a composição de uma URL. https://www.youtube.com/results?search_query=dance+music

Ao analisar a url acima, podemos dividi-la em 6 partes, sendo elas:

Nesse cenário, o que mais nos interessa é a query string, a parte final da URL. Uma query string é um conjunto de chave=valor separado por um =. O trecho de query string é separado do resto da url por um ? e podemos ter várias query strings separadas por um &.

Alguns exemplos de ulr com query string:

URL explicada

Para saber mais sobre a estrutura de uma URL recomendo a leitura do artigo Anatomia de uma URL.

Como usar a URL como state?

Nas URLs acima você pode ter notado algumas informações interessantes, como categoria selecionada ou número da página. Podemos facilmente recuperar e atualizar essas informações em nossa aplicação.

Pensando no nosso problema inicial, nossa URL poderia ficar dessa forma: https://www.meusite.com/pagina-da-produtos?stock=2&category=beauty&search=lipstick

E o nosso código ficaria assim:

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

export function HomePage() {
  const [searchParams, setSearchParams] = useSearchParams();

  function submitForm(e) {
    e.preventDefault();
    const search = e.currentTarget['search']?.value;
    const category = e.currentTarget['category']?.value;
    const stock = e.currentTarget['stock']?.value;

    setSearchParams({ search, category, stock });
  }

  ....
}

Por fim, nossa listagem precisa capturar as informações da URL. Podemos fazer isso usando o searchParams, que é retornado pelouseSearchParams(). Ao recuperar essas informações e aplicar os filtros, nosso código ficará assim:

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

export function Home() {
  const [data, setData] = React.useState([]);
  const [searchParams] = useSearchParams();
  function filterData(data) {
    let filterValues = {};

    // Populando filterValues com os parâmetros de busca
    searchParams.forEach((v, k) => {
      filterValues[k] = v;
    });

    // Se não houver nenhum filtro, retorna a lista completa
    if (Object.keys(filterValues).length === 0) {
      return data;
    }

    return data.filter((item) => {
      let isMatch = true;

      // Verificação dos filtros
      if (filterValues.category && item.category !== filterValues.category) {
        isMatch = false;
      }

      if (filterValues.stock && item.stock !== Number(filterValues.stock)) {
        isMatch = false;
      }

      if (
        filterValues['search'] &&
        !item.description
          .toLowerCase()
          .includes(filterValues['search'].toLowerCase())
      ) {
        isMatch = false;
      }

      return isMatch;
    });
  }

Para entender mais sobre o funcionamento você pode ver e editar o código que acabamos de construir no stackblitz. Importante ressaltar que para funcionar você deve abrir o projeto em uma nova aba.

URL State não é bala de prata!

Como qualquer tecnologia, é importante analisar cuidadosamente antes de utilizar o URL State.

Aqui estão alguns casos em que o URL State pode ser útil:

Por outro lado, existem cenários em que o uso do URL State pode não ser a melhor alternativa. Alguns exemplos são:

Além desses pontos, é importante ter cuidado com o uso excessivo do URL State. Dependendo de como a URL é manipulada, pode haver impacto no desempenho da aplicação, especialmente se o estado for muito grande ou precisar ser processado frequentemente. Em alguns casos, cada alteração na URL pode causar a rerenderização de toda a cadeia de componentes, como no React, por exemplo.

Na maioria dos casos, você não precisará usar a URL como state. Analise cuidadosamente cada cenário antes de adicionar estado às suas URLs, pois, apesar dos benefícios, há desvantagens a serem consideradas, além do custo de manutenção.

Muito obrigado!!

Obrigado por ter chegado até aqui!

Espero que tenha aprendido algo novo ao longo dessa leitura.

Até a próxima!