SWR nos disponibiliza React Hooks para realizar requisições, com a estratégia de stale-while-revalidate de forma padrão. SWR consiste em a primeira vista, temos os dados do cache (stale) e enquanto isso,uma requisição é enviada (revalidate) para validar esse cache, e por fim, se houver alguma mudança, os dados são atualizados.
Sugiro a leitura das principais funcionalidades do SWR
SWR: React Hooks for Data Fetching
Sem mais enrolação, bora pro código!
Primeiro de tudo, vamos iniciar o nosso projeto e instalar o SWR
Vou utiilizar um template com Typescript
yarn create react-app swr-basics --template typescript
Após o setup, vamos adcionar o SWR
yarn add swr
Para todas as requisições que vamos utilizar o SWR, vamos precisar de uma fetcher function, que será uma função assíncrona que simplesmente retorna os dados. Para isso podemos utilizar tanto a API de fetch do próprio javascript, ou bibliotecas como axios. E para enviarmos requisições a APIs GraphQL, vamos precisar utilizar algum GraphQL Client
E nesse caso vamos usar o graphql-request
yarn add graphql-request graphql
Além de todas essas libs, vamos precisar de alguma API GraphQL, para enviar nossas queries. Sendo assim, vamos utilizar uma API incrível da SpaceX
Para começar, vamos enviar uma query buscando por foguetes 🚀
{
rockets {
active
name
mass {
kg
}
description
}
}
Para isso, vamos criar o nosso componente que vai realizar a requisição e mostrar na tela os dados dos foguetes
Rockets.tsx
import { FunctionComponent } from "react";
const Rockets: FunctionComponent = () => {
return (
<div>
<span>Rockets will land here</span>
</div>
);
};
export default Rockets;
E nosso App.tsx vai ficar assim:
import "./app.css";
import Rockets from "./components/Rockets";
const App = () => {
return (
<div className="App">
<Rockets />
</div>
);
};
export default App;
Certo, agora pra que tudo funcione, vamos criar um arquivo com uma configuração básica do nosso GraphQL Client, onde vamos inserir a rota para a API da SpaceX
Também é possível adicionarmos outras opções, como headers, credentials, e etc...
graphqlClient.ts
import { GraphQLClient } from "graphql-request";
export const graphqlClient = new GraphQLClient(
"https://api.spacex.land/graphql/"
);
Com nosso cliente GraphQL, vamos começar enviando a nossa query
Para isso vamos criar a nossa fetcher function
Rockets.tsx
import { FunctionComponent } from "react";
import { RequestDocument } from "graphql-request/dist/types";
import { graphqlClient } from "../graphql/graphqClient";
const Rockets: FunctionComponent = () => {
const fetcher = (query: RequestDocument) => graphqlClient.request(query)
return (
<div>
<span>Rockets will land here</span>
</div>
);
};
export default Rockets;
E esse RequestDocument será a nossa query que vamos enviar para buscar os foguetes
Podemos escreve-la assim:
const rocketsQuery = `
{
rockets {
active
name
mass {
kg
}
description
}
}
`
E tudo que precisamos fazer é passar ela para o hook useSWR, juntamente com a nossa função fetcher
E desse hook podemos obter data e error
const { data, error } = useSWR(rocketsQuery, fetcher)
E podemos mostrar na tela se existir algum dado:
if (data) {
return (
<div>
<pre>{JSON.stringify(data, null, 2)}</pre>
</div>
);
}
Rockets.tsx
import { FunctionComponent } from "react";
import { RequestDocument } from "graphql-request/dist/types";
import { graphqlClient } from "../graphql/graphqClient";
import useSWR from "swr";
const Rockets: FunctionComponent = () => {
const fetcher = (query: RequestDocument) => graphqlClient.request(query);
const rocketsQuery = `
{
rockets {
active
name
mass {
kg
}
description
}
}
`;
const { data, error } = useSWR(rocketsQuery, fetcher);
if (data) {
return (
<div>
<pre>{JSON.stringify(data, null, 2)}</pre>
</div>
);
}
if (error) {
return (
<div>
<pre>Something went bad :(</pre>
</div>
);
}
return (
<div>
<span>Loading rockets...</span>
</div>
);
};
export default Rockets;
Se tudo ocorreu bem, teremos um JSON com os foguetes
Irado! 🤘🏼
Agora que já pegamos a ideia da coisa, vamos enviar uma mutation para a API, criando um usuário
A mutation vai ser assim:
mutation {
insert_users(objects: {name: "Vinicius", rocket: "El Jalapeño Rocket"}) {
returning {
id
name
rocket
}
}
}
E a query para buscar os usuáros
{
users {
id
name
rocket
}
}
Então bora começar criando um componente para listar os usuários
E assim como nossa query de foguetes, vamos criar nossa fetcher function, adicionar nossa query de usuários, e por fim, nosso hook useSWR
Users.tsx
import { FunctionComponent } from "react";
import { RequestDocument } from "graphql-request/dist/types";
import { graphqlClient } from "../graphql/graphqClient";
import useSWR from "swr";
const Users: FunctionComponent = () => {
const fetcher = (query: RequestDocument) => graphqlClient.request(query);
const usersQuery = `
{
users {
id
name
rocket
}
}
`;
const { data, error } = useSWR(usersQuery, fetcher);
...
};
export default Users;
Agora vamos colocar na tela os usuários, e enquanto eles não aparecem, podemos mostrar um "Loading..." na tela
Users.tsx
if (data) {
return (
<div>
<div>
<pre>{JSON.stringify(data, null, 2)}</pre>
</div>
</div>
);
}
if (error) {
return <div>Something went bad!</div>;
}
return (
<div>
<span>Loading Users...</span>
</div>
);
Então, temos um JSON com os usuários
Nice! 🤘🏼
Por fim, vamos criar um formulário para adicionar um novo usuário, e ver se ele aparece na nossa lista de usuários
UserForm.tsx
import { FormEvent, FunctionComponent, useState } from "react";
const UserForm: FunctionComponent = () => {
const [username, setUsername] = useState<string>("");
const [rocketName, setRocketName] = useState<string>("");
const handleCreateuser = async (event: FormEvent<HTMLFormElement>) => {
event.preventDefault();
console.log({username, rocketName})
};
return (
<form onSubmit={(event) => handleCreateuser(event)}>
<input
type="text"
placeholder="username"
value={username}
onChange={(event) => setUsername(event.target.value)}
/>
<input
type="text"
placeholder="rocket name"
value={rocketName}
onChange={(event) => setRocketName(event.target.value)}
/>
<button>Create User</button>
</form>
);
};
export default UserForm;
Por enquanto, nosso componente está apenas fazendo um log com os valores dos inputs
Agora precisamos criar uma mutation, passando esses valores
Essa é a mutation para inserir usuários
mutation insertUsers($name: String!, $rocket: String!){
insert_users(objects: {name: $name, rocket: $rocket}) {
returning {
id
name
rocket
}
}
}
E agora junto com a mutation, utlizando o graphql-request, vamos passar as variáveis que vamos criar o usuário
UserForm.tsx
const [username, setUsername] = useState<string>("");
const [rocketName, setRocketName] = useState<string>("");
const createUserMutation = `
mutation insertUsers($name: String!, $rocket: String!){
insert_users(objects: {name: $name, rocket: $rocket}) {
returning {
id
name
rocket
}
}
}
`;
const handleCreateuser = async (event: FormEvent<HTMLFormElement>) => {
event.preventDefault();
const response = await graphqlClient.request(createUserMutation, {
name: username,
rocket: rocketName,
});
console.log(response);
};
Agora assim que enviarmos a nossa mutation, nossa query de users vai notar que houve uma mudança, e irá revalidar os dados, carregando o nosso novo usuário na tela.
Então o resultado final será esse:
UserForm.tsx
import { FormEvent, FunctionComponent, useState } from "react";
import { graphqlClient } from "../graphql/graphqClient";
const UserForm: FunctionComponent = () => {
const [username, setUsername] = useState<string>("");
const [rocketName, setRocketName] = useState<string>("");
const createUserMutation = `
mutation insertUsers($name: String!, $rocket: String!){
insert_users(objects: {name: $name, rocket: $rocket}) {
returning {
id
name
rocket
}
}
}
`;
const handleCreateuser = async (event: FormEvent<HTMLFormElement>) => {
event.preventDefault();
const response = await graphqlClient.request(createUserMutation, {
name: username,
rocket: rocketName,
});
console.log(response);
};
return (
<form onSubmit={(event) => handleCreateuser(event)}>
<input
type="text"
placeholder="username"
value={username}
onChange={(event) => setUsername(event.target.value)}
/>
<input
type="text"
placeholder="rocket name"
value={rocketName}
onChange={(event) => setRocketName(event.target.value)}
/>
<button>Create User</button>
</form>
);
};
export default UserForm;
E podemos fazer um teste:
E após enviarmos o formulário, a nossa query de users vai revalidar a requisição e assim que tiver algum novo usuário, vamos ter a atualização na tela.
Incrível! 🔥
Espero que agora as requisições para APIs GraphQL utilizando SWR tenha ficado mais claro. E caso precise de alguma ajuda, mande uma mensagem 👍🏼
Se esse post foi útil, e te ajudou de alguma maneira, deixe uma reação e me siga nas redes.
Happy Coding!
Links úteis:
Top comments (1)
Obrigado pelos exemplos!