Skip to content

Instantly share code, notes, and snippets.

@geovanisouza92
Last active February 6, 2022 17:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save geovanisouza92/966b23da061d5d7892116a5f5b641d73 to your computer and use it in GitHub Desktop.
Save geovanisouza92/966b23da061d5d7892116a5f5b641d73 to your computer and use it in GitHub Desktop.
Prefetch de dados SSR com react-query

Vantagem: a página é carregada já com dados, logo, se o usuário está com uma máquina mais modesta ou internet mais lenta, vai evitar loading/spinner.

// lib/notes.js
// Podemos usar a mesma função compartilhada no servidor (SSR) e navegador (CSR)
async function fetchNotes() {
return await fetch('/api/notes').then(res => res.json());
}
// pages/_app.jsx
import { Hydrate, QueryClient, QueryClientProvider } from 'react-query';
export default function CustomApp({ Component, pageProps }) {
const [queryClient] = useState(() => new QueryClient());
return (
<QueryClientProvider queryClient={queryClient}>
{/*
Aqui re-hidratamos as consultas pré-carregadas no getServerSideProps
da página (qualquer que seja)
Se a página não tiver getServerSideProps ou não retornar
initialQueries, o <Hydrate /> não fará nada.
*/}
<Hydrate state={pageProps.initialQueries}>
<Component {...pageProps} />
</Hydrate>
</QueryClientProvider>
);
}
// pages/notes.jsx
import { dehydrate, QueryClient, useQuery } from 'react-query';
import { fetchNotes } from './lib/notes';
// Essa função é executada no servidor pra cada requisição.
//
// O objetivo é pre-carregar os dados da página que fazem parte do
// "hot-path", tudo que é essencial que esteja visível pro usuário
// assim que possível.
export async function getServerSideProps() {
const queryClient = new QueryClient();
await queryClient.prefetchQuery(['notes', 'list'], fetchNotes);
// Listamos quaisquer outras queries que precisem ser carregadas.
//
// Se quisermos carregar várias ao mesmo tempo, podemos usar:
//
// await Promise.all([
// queryClient.prefetchQuery(['boards'], fetchBoards),
// queryClient.prefetchQuery(['edges'], fetchEdges),
// queryClient.prefetchQuery(['components'], fetchComponents),
// ]);
//
// Mas isso só funciona para queries que não são dependentes entre si.
return {
props: {
// Desidrata o estado do QueryClient para o cliente.
//
// O <Hydrate /> em pages/_app.jsx fará o resto.
initialQueries: dehydrate(queryClient),
},
};
}
export default function NotesPage() {
// Aqui usamos o QueryClient do contexto para carregar as queries
// que foram carregadas no getServerSideProps.
//
// Isso permite que a página tenha uma primeira versão "stale" dos
// dados e renderize imediatamente.
//
// Logo em seguida, uma revalidação (nova requisição) será feita
// para atualizar os dados. É possível aumentar o staleTime para
// atrasar essa revalidação.
const { data } = useQuery(['notes', 'list'], fetchNotes);
// ...
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment