Saltar al contenido principal

useFetch()

Obtiene un Endpoint si no está en la caché o está obsoleto. Devuelve un Ref que contiene la promesa del fetch (con un indicador resolved). Se dispara un nuevo fetch cuando cambian los argumentos o cuando los datos se invalidan. Úsalo para iniciar los fetches temprano y luego lee los datos con useSuspense(), useCache() o useDLE().

Uso​

Carga de datos en paralelo​

await useSuspense() se ejecuta secuencialmente en <script setup>. Llamar primero a useFetch() para cada endpoint inicia todos los fetches en paralelo; las llamadas posteriores a useSuspense() reutilizan las peticiones en curso.

<script setup lang="ts">
  import { useFetch, useSuspense } from '@data-client/vue';
  import { PostResource, CommentResource } from './Resources';

  const props = defineProps<{ id: number }>();

  // Both fetches start in parallel
  useFetch(PostResource.get, () => ({ id: props.id }));
  useFetch(CommentResource.getList, () => ({ postId: props.id }));

  // useSuspense() reads the results — the second fetch
  // is already in-flight while the first one is awaited
  const post = await useSuspense(PostResource.get, () => ({ id: props.id }));
  const comments = await useSuspense(CommentResource.getList, () => ({
    postId: props.id,
  }));
</script>

<template>
  <article>
    <h3>{{ post.title }}</h3>
    <p>{{ post.body }}</p>
    <h4>Comments</h4>
    <div v-for="comment in comments" :key="comment.id" class="listItem">
      <strong>{{ comment.author }}</strong>: {{ comment.text }}
    </div>
  </article>
</template>

Precarga​

useFetch() también se puede usar de forma independiente para asegurar que los recursos estén disponibles temprano en el árbol de renderizado, antes de que se necesiten.

consejo

Úsalo junto con un hook de enlace de datos (useCache(), useSuspense(), useDLE(), useLive()) en otro componente.

MasterPost.vue
<script setup lang="ts">
import { useFetch } from '@data-client/vue';
import { PostResource } from './Resources';

const props = defineProps<{ id: number }>();
useFetch(PostResource.get, () => ({ id: props.id }));
// ...
</script>

Comportamiento​

Estado de caducidadFetch.valueresolvedCondiciones
Inválidosí1promesa pendientefalseno está en el store, eliminación, invalidación
Obsoletosí1promesa pendientefalse(primer render, cambio de args) & caducidad < ahora
Válidonopromesa resueltatruefetch completado
Errornopromesa rechazadatrueel fetch falló
noundefinedse usó null como segundo argumento

El Ref devuelto se actualiza con una nueva promesa cada vez que se dispara un fetch: al cambiar los argumentos, tras una invalidación o un reinicio.

nota
  1. Los fetches idénticos se deduplican automáticamente
Dependencias condicionales

Usar null como segundo argumento de cualquier hook de Data Client significa "no hacer nada".

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

Tipos​

function useFetch(
endpoint: ReadEndpoint,
...args: MaybeRefsOrGetters<Parameters<typeof endpoint>> | [null]
): Readonly<
Ref<
| (Promise<Denormalize<typeof endpoint.schema>> & {
resolved: boolean;
})
| undefined
>
>;

Los argumentos pueden ser valores simples, refs (incluidos los computed) o funciones getter como () => ({ id: props.id }). Un objeto simple como { id: props.id } se lee una sola vez y no seguirá los cambios de props ni de ruta, así que usa un getter o computed cuando un argumento pueda cambiar.

Se dispara un nuevo fetch cuando cambian los argumentos.

Ejemplos​

Comprobar el estado del fetch​

Usa promise.resolved para comprobar si los datos aún se están cargando:

MasterPost.vue
<script setup lang="ts">
import { useFetch } from '@data-client/vue';
import { PostResource } from './Resources';

const props = defineProps<{ id: number }>();
const promise = useFetch(PostResource.get, () => ({ id: props.id }));
if (promise.value && !promise.value.resolved) {
// fetch is in-flight
}
// ...
</script>