Pular para o conteúdo principal

useFetch()

Busca um Endpoint se ele não estiver em cache ou estiver desatualizado. Retorna um thenable que funciona com React.use() -- use(useFetch(endpoint, args)) opera como useSuspense(): suspende enquanto os dados carregam, retorna os dados desnormalizados quando disponíveis e suspende novamente na invalidação.

Uso​

Carregamento de dados em paralelo​

Como useFetch() e use() são chamadas separadas, vários fetches começam em paralelo — mesmo quando o primeiro use() suspende. Veja o exemplo de fetches em paralelo abaixo.

import { use } from 'react';
import { useFetch } from '@data-client/react';
import { PostResource, CommentResource } from './Resources';

function PostWithComments({ id }: { id: number }) {
  // Both fetches start in parallel
  const postPromise = useFetch(PostResource.get, { id });
  const commentsPromise = useFetch(CommentResource.getList, {
    postId: id,
  });

  // use() reads the results — if the first suspends,
  // the second fetch is already in-flight
  const post = use(postPromise);
  const comments = use(commentsPromise);

  return (
    <article>
      <h3>{post.title}</h3>
      <p>{post.body}</p>
      <h4>Comments</h4>
      {comments.map(comment => (
        <div key={comment.id} className="listItem">
          <strong>{comment.author}</strong>: {comment.text}
        </div>
      ))}
    </article>
  );
}
render(<PostWithComments id={1} />);
Resultado
Store▶

Prefetching​

useFetch() também pode ser usado de forma independente para garantir que os recursos estejam disponíveis cedo na árvore de renderização, antes de serem necessários.

dica

Use em combinação com um hook de vinculação de dados (useCache(), useSuspense(), useDLE(), useLive()) em outro componente.

import { useFetch } from '@data-client/react';
import { PostResource } from './resources/Post';

function MasterPost({ id }: { id: number }) {
useFetch(PostResource.get, { id });
// ...
}

Comportamento​

Status de expiraçãoFetchComportamento de use()resolvedCondições
Inválidosim1suspendefalsenão está na store, exclusão, invalidação
Desatualizadosim1suspendefalse(primeira renderização, mudança de args) & expiração < agora
Válidonãoretorna dadostrueconclusão do fetch
Erronãolança errotruefetch falhou, capturado por Error Boundary
nãoundefinednull usado como segundo argumento

Quando a store é atualizada (por exemplo, via mutações ou Controller.set()), o componente é renderizado novamente e useFetch() retorna automaticamente os dados desnormalizados atualizados.

observação
  1. Fetches idênticos são automaticamente deduplicados
React Native

Ao usar o React Navigation, useFetch() dispara fetches ao receber foco se os dados forem considerados desatualizados.

Dependências condicionais

Usar null como segundo argumento de qualquer hook do Data Client significa "não fazer nada."

// todo could be undefined if id is undefined
const todo = useFetch(TodoResource.get, id ? { id } : null);

Tipos​

function useFetch(
endpoint: ReadEndpoint,
...args: Parameters<typeof endpoint> | [null]
): (PromiseLike<any> & { resolved: boolean }) | undefined;

Exemplos​

Verificando o status do fetch​

Use promise.resolved para verificar se os dados ainda estão carregando:

import { useFetch } from '@data-client/react';
import { PostResource } from './resources/Post';

function MasterPost({ id }: { id: number }) {
const promise = useFetch(PostResource.get, { id });
if (!promise.resolved) {
// fetch is in-flight
}
// ...
}

Preload no NextJS​

Para evitar waterfalls de fetch no NextJS, às vezes você pode precisar adicionar preloads às rotas de nível superior.

More Demos