Executando verificação de segurança...
3

React: Não use o useEffect?

Esse post não busca te convencer a parar de usar o useEffect, até porque não tem como não usar, mas nem sempre é preciso dele e eu quero te mostrar como e porque. E isso ainda vai te ajudar a deixar seu código mais limpo 😉, o famoso clean code.

O que vamos usar?

Suspense (React) + useSWR (Vercel ❤️).

Quando removemos o useEffect?

A primeira requisição que a página ou o componente faz.

O fluxo que aprendemos normalmente quando queremos fazer uma requisição assim que a página carrega é da seguinte forma:

...
const [users, setUsers] = useState([]);

useEffect(() => {
    axios.get("/url-da-api")
      .then(({ data }) => data)
      .then((resUsers) => setUsers(resUsers));
}, []);
...

Certo, e se você quiser um loading? Aí precisa adicionar um loading state e setar como false ao fim da requisição:

...
const [users, setUsers] = useState([]);
const [isLoading, setIsLoading] = useState(true);

useEffect(() => {
    axios.get("/url-da-api")
      .then(({ data }) => data)
      .then((resUsers) => setUsers(resUsers))
      .finally(() => setIsLoading(false));
}, []);
...

Também não pode deixar de tratar o catch até porque não vivemos em mundo perfeito.

...
const [users, setUsers] = useState([]);
const [isLoading, setIsLoading] = useState(true);
const [hasError, setHasError] = useState(false);

useEffect(() => {
    axios.get("/url-da-api")
      .then(({ data }) => data)
      .then((resUsers) => setUsers(resUsers))
      .catch(() => setHasError(true))
      .finally(() => setIsLoading(false));
}, []);
...

E isso tudo porque nem falamos de UI ainda, e todo o código para fazer isso ficar agradável...

Agora sim! Como fariamos sem o useEffect?

Primeiro você precisa instalar o useSWR, também é muito importante olhar a documentação (depois de ler e aplicar esse conteúdo).

npm install swr ou yarn add swr

E depois você pode importar

import useSWR from swr;

Eu geralmente uso da seguinte forma para evitar que ele fique revalidando (refazendo a requisição para ver se tem algum conteúdo novo)

import useSWR from "swr/immutable";

Depois disso você consegue substituir nosso useEffect (e de bônus o useState também) por:

...
const fetcher = (url) => axios.get(url)
    .then(({ data }) => data);

const { data:users } = useSWR("/url-da-api", fetcher, { suspense: true });
...

É isso... Simples assim, mas nesse ponto seu código NÃO VAI ESTAR FUNCIONARNDO, pois agora que vem o React.Suspense. Percebe o ...{ suspense: true }); ao final do nosso código? Ele serve para deixar o nosso componente em estado de loading. Mas como vamos mostrar um "Carregando..." ou um Skeleton?

Aplicando o React.Suspense

Vamos dizer que o nosso código faz parte de um componente UsersTable, e nesse momento estamos carregando ele dentro do UsersPage.

...
function UsersPage() {
    return (
        <div>
            <h1>Users</h1>
            
            <UsersTable />
        </div>
    );
}
...

Ao carregar o <UsersTable />, nesse momento ele vai quebrar a página pois ele está fazendo a requisição na api e em momento algum foi tratado isso no código.

Primeiro vamos importar o Suspense diretamente do React:

import { Suspense } from "react";
...

E envolver nosso componente <UsersTable /> em um Suspense:

...
<Suspense>
    <UsersTable />
<Suspense>
...

E por fim adicionar um atributo fallback, com componente ou tag, ao suspense para mostrar o "Carregando...".

...
<Suspense fallback={<span>Carregando...</span>}>
    <UsersTable />
<Suspense>
...

E está pronto, agora é só dá uma conferida na documentação do useSWR para ver mais forma de usar, e você pode até mesmo usar sem o Suspense.

Dica extra: E se a requisição falhar? 🤔

Boa, então você se preocupa com diferentes cenários né?! Se a nossa "inquebrável" api quebrar o que acontece? Sua página inteira quebra!

Mas não precisa ser assim, e em conjunto com tudo que aprendemos também vamos ver como resolver essa situação, e tornar seu front inquebrável.

Vamos começar instalando o ErrorBoundary:

npm install react-error-boundary ou yarn add react-error-boundary

E depos você pode importar:

import { ErrorBoundary } from "react-error-boundary";
...

Da mesma forma como você usou o Suspense você vai usar o ErrorBoundary. Ou seja, envolve o componente nele e passa um fallback, e vale a pena saber que ele vai pegar todos os erros do código, não só o dá requisição.

...
<ErrorBoundary fallback={<span>Ops! Algo deu errado!</span>}>
    <Suspense fallback={<span>Carregando</span>}>
        <UsersTable />
    <Suspense>
<ErrorBoundary fallback={<span>Carregando</span>}>
...

O mais legal disso tudo é que o UsersPage não vai quebrar como normalmente ocorre quando um componente interno quebra, apenas o seu UsersTable vai quebrar de forma isolada, mostrando o conteúdo do fallback: <span>Ops! Algo deu errado!</span>

Dica: Para debuggar componentes que estão envolvidos em ErrorBoundary, use o console do seu browser.

Carregando publicação patrocinada...
1
1

Boa! Estou buscando formas de fazer comunição com meus endpoints de forma mais fluída e rapida. Irei testar, está na minha lista também dar uma olhada no useQuery. Obrigado por compartilhar.