Skip to content

fix: make queryKey reactive for dynamic input changes (#fix-reactive-…#239

Open
zxzinn wants to merge 1 commit intowobsoriano:mainfrom
zxzinn:zxzinn/fix-reactive-query-key
Open

fix: make queryKey reactive for dynamic input changes (#fix-reactive-…#239
zxzinn wants to merge 1 commit intowobsoriano:mainfrom
zxzinn:zxzinn/fix-reactive-query-key

Conversation

@zxzinn
Copy link

@zxzinn zxzinn commented Jan 24, 2026

Fix: Make queryKey reactive for dynamic input changes

Problem

When using useQuery with a reactive input (e.g., a computed), the queryKey is computed once at call time and never updates. This causes useAsyncData to use a stale cache key, returning incorrect cached data when the input changes.

Reproduction

<script setup>
const selectedId = ref(1)

// When selectedId changes, the query fetches new data
// but useAsyncData returns cached data from the OLD queryKey
const { data } = await trpc.item.get.useQuery(
  computed(() => ({ id: selectedId.value }))
)
</script>

Expected: When selectedId changes from 1 to 2, the query should return data for item 2.

Actual: The query fetches item 2 from the server, but useAsyncData returns cached data for item 1 because the queryKey is still based on the initial input.

Root Cause

In decoration-proxy.ts line 33:

const queryKey = customQueryKey || getQueryKeyInternal(path, toValue(input));

queryKey is computed once when handleUseQuery is called. Even though input is reactive, queryKey becomes a static string value that never updates.

Solution

Make queryKey a getter function so it re-evaluates when input changes:

const queryKey = customQueryKey
  ? (isRefOrGetter(customQueryKey) ? customQueryKey : () => customQueryKey)
  : () => getQueryKeyInternal(path, toValue(input));

This ensures:

  • When input is reactive, queryKey returns a new cache key based on the current input value
  • When customQueryKey is provided as a ref/getter, it's passed through as-is
  • When customQueryKey is a static value, it's wrapped in a getter for consistency

Testing

  1. Create a component with useQuery using a computed input
  2. Change the input value
  3. Verify the returned data matches the new input (not cached data from the old input)

…query-key)

Make queryKey a getter so it updates when input changes.
This ensures useAsyncData uses the correct cache key for
reactive inputs.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant