SuperAPI AI Directory

tanstack-query-intent-framework-use-framework-adapter-reactivity

Frontend & websites

View repository

Updated 10-16 00:02

About this skill

This skill builds on lifecycle/setup-query-client-and-providers and core/design-query-keys-and-options.

Setup

import { queryOptions } from '@tanstack/react-query'

export function todoOptions(id: string) {
  return queryOptions({
    queryKey: ['todo', id],
    queryFn: async () => ({ id }),
  })
}

Hooks and Components

Keep Vue refs in the key

import { computed, toRef } from 'vue'
import { useQuery } from '@tanstack/vue-query'

export function useTodo(props: { id: string }) {
  const id = toRef(props, 'id')
  return useQuery(
    computed(() => ({
      queryKey: ['todo', id.value],
      queryFn: async () => ({ id: id.value }),
    })),
  )
}

Use Solid option functions

import { createQuery } from '@tanstack/solid-query'

export function useTodo(id: () => string) {
  return createQuery(() => ({
    queryKey: ['todo', id()],
    queryFn: async () => ({ id: id() }),
  }))
}

Convert Angular Observable clients to promises

import { injectQuery } from '@tanstack/angular-query-experimental'
import { firstValueFrom, of } from 'rxjs'

export class TodosQuery {
  todos = injectQuery(() => ({
    queryKey: ['todos'],
    queryFn: () => firstValueFrom(of([{ id: 1 }])),
  }))
}

Common Mistakes

HIGH Vue ref unwrapped

Wrong:

import { useQuery } from '@tanstack/vue-query'

export function useTodo(id: { value: string }) {
  return useQuery({
    queryKey: ['todo', id.value],
    queryFn: async () => ({ id: id.value }),
  })
}

Correct:

import { computed } from 'vue'
import { useQuery } from '@tanstack/vue-query'

export function useTodo(id: { value: string }) {
  return useQuery(
    computed(() => ({
      queryKey: ['todo', id.value],
      queryFn: async () => ({ id: id.value }),
    })),
  )
}

Vue reactive inputs need to stay reactive through the options object or query key.

Source: TanStack/query:docs/framework/vue/reactivity.md

HIGH Svelte store syntax in v6

Wrong:

<script lang="ts">
  import { createQuery } from '@tanstack/svelte-query'
  const query = createQuery({ queryKey: ['todos'], queryFn: async () => [] })
</script>

Correct:

<script lang="ts">
  import { createQuery } from '@tanstack/svelte-query'
  const query = createQuery(() => ({
    queryKey: ['todos'],
    queryFn: async () => [],
  }))
</script>

Svelte Query v6 uses rune-compatible option functions rather than the older store shape.

Source: TanStack/query:docs/framework/svelte/migrate-from-v5-to-v6.md

HIGH Angular Observable returned directly

Wrong:

import { injectQuery } from '@tanstack/angular-query-experimental'
import { of } from 'rxjs'

export class TodosQuery {
  todos = injectQuery(() => ({
    queryKey: ['todos'],
    queryFn: () => of([{ id: 1 }]),
  }))
}

Correct:

import { injectQuery } from '@tanstack/angular-query-experimental'
import { firstValueFrom, of } from 'rxjs'

export class TodosQuery {
  todos = injectQuery(() => ({
    queryKey: ['todos'],
    queryFn: () => firstValueFrom(of([{ id: 1 }])),
  }))
}

Query functions must resolve data; Angular HttpClient Observables need conversion to promises.

Source: TanStack/query:docs/framework/angular/angular-httpclient-and-other-data-fetching-clients.md

See also: core/design-query-keys-and-options for key identity across adapters.