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} />);
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.
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ção | Fetch | Comportamento de use() | resolved | Condições |
|---|---|---|---|---|
| Inválido | sim1 | suspende | false | não está na store, exclusão, invalidação |
| Desatualizado | sim1 | suspende | false | (primeira renderização, mudança de args) & expiração < agora |
| Válido | não | retorna dados | true | conclusão do fetch |
| Erro | não | lança erro | true | fetch falhou, capturado por Error Boundary |
| não | undefined | null 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.
- Fetches idênticos são automaticamente deduplicados
Ao usar o React Navigation, useFetch() dispara fetches ao receber foco se os dados forem considerados desatualizados.
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
- Type
- With Generics
function useFetch(
endpoint: ReadEndpoint,
...args: Parameters<typeof endpoint> | [null]
): (PromiseLike<any> & { resolved: boolean }) | undefined;
function useFetch<
E extends EndpointInterface<
FetchFunction,
Schema | undefined,
undefined
>,
Args extends readonly [...Parameters<E>] | readonly [null],
>(endpoint: E, ...args: Args): UsablePromise<Denormalize<E['schema']>>;
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.
Explore o exemplo