Novo hook do react que promete simplificar requisições assíncronas
Ok, não tão novo assim... O use()
hook foi apresentado através de um RFC em novembro de 2022 juntamente do suporte para async/await
em componentes do servidor usando React Server Components.
E por mais que o nome seja meio estranho... (parece que ficaram meio sem ideias de nome kkk) Ele é incrível! E promete facilitar muito o processo de fazer requisições assíncronas no React.
Diferentemente dos componentes de servidor, o use()
é um hook que pode ser utilizado no cliente, e a principal ideia é trazer um suporte para tratar requisições assíncronas utilizando o <Suspense>
, que é uma forma de tratar estados de carregamento de funções assíncronas direto do React (caso queira entender melhor veja a documentação oficial).
Pode parecer meio confuso a primeira vista, mas a melhor maneira de explicar isso é mostrando como funciona na prática.
Primeiramente, vejamos uma forma "padrão" de criar um componente que faz uma requisição para uma API externa
import React, { useEffect, useState } from "react";
const OldFetch = ({ url }) => {
const [data, setData] = useState();
const [loading, setLoading] = useState(false);
const [error, setError] = useState();
useEffect(() => {
setLoading(true);
setError(false);
setData(undefined);
fetch(url)
.then((response) => response.json())
.then(setData)
.catch(() => setError(true))
.finally(() => {
setLoading(false);
});
}, [url]);
return loading ? (
<div>Carregando...</div>
) : error ? (
<div>Erro ao carregar os dados</div>
) : (
<div>
<h1>Antigo react:</h1>
<pre> {JSON.stringify(data, null, 2)}</pre>
</div>
);
};
export default OldFetch;
Essa é uma forma mais simples possível utilizando conceitos antigos do React para fazer um fetch, contudo, atualmente existem diversas bibliotecas que visam justamente simplificar esse processo, como o React Query ou o SWR
Utilizando o React Query nosso código ficaria mais ou menos assim
import { useQuery } from "@tanstack/react-query";
import React from "react";
const ReactQuery = ({ url }) => {
const { data, isLoading, isError } = useQuery({
queryKey: ["get_url"],
queryFn: () => fetch(url).then((res) => res.json()),
});
return isLoading ? (
<div>Carregando...</div>
) : isError ? (
<div>Erro ao carregar os dados</div>
) : (
<div>
<h1>React-query:</h1>
<pre> {JSON.stringify(data, null, 2)}</pre>
</div>
);
};
export default ReactQuery;
Uma quantidade significativamente menos verbosa de código, o React query fica responsável por proporcionar estados de erro e de carregamento, o que faz com que nem seja necessário utilizar outros hooks como o useState()
ou useEffect()
OBS: Algumas outras configurações precisam ser realizadas no react-query, como a definição de um QueryClient
A solução proporcionada pelo novo hook use()
é parecida com essa, o nosso código fica assim:
import React, { use } from "react";
const NewFetch = ({ url }) => {
const data = use(
fetch(url)
.then((res) => res.json())
.catch((err) => {
// Tratar o erro de forma adequada aqui
console.error("Erro ao carregar os dados", err);
})
);
return (
<div>
<h1>Novo fetch usando {'use()'} hook </h1>
<pre> {JSON.stringify(data, null, 2)}</pre>
</div>
);
};
export default NewFetch;
Porém você pode estar se perguntando, cadê o estado de carregamento? É ai que o <Suspense>
é utilizado, encapsulando o nosso componente de fetch e permitindo um "Fallback" enquanto os dados estão carregando.
import { Suspense } from "react";
import NewFetch from "./components/NewFetch";
import OldFetch from "./components/OldFetch";
import ReactQuery from "./components/ReactQuery";
function App() {
const defaultUrl = "https://jsonplaceholder.typicode.com/posts";
return (
<>
{/* <OldFetch url={defaultUrl} /> */}
<Suspense fallback={<div> Carregando... </div>}>
<NewFetch url={defaultUrl} />
</Suspense>
{/* <ReactQuery url={defaultUrl} /> */}
</>
);
}
export default App;
Dessa forma, é possível ver que o processo de requisições assíncronas fica muito simplificado utilizando o use()
, especialmente quando comparado com a forma "antiga" de fazer isso.
Contúdo, é importante notar que o use()
não é uma solução tão completa como o uso de alguma biblioteca como o React-query ou SWR, que proporcionam diversas outras features como cache automático dos dados, revalidação, mutations e muito muito mais.
De toda forma é interessante ver os avanços do React para tornar a biblitoeca cada vez mais completa!
Um vídeo que recomendo para entender melhor o hook caso tenham restado dúvidas é o This New React Hook Breaks All The Rules And I Love It