Skip to content

Vue example has a reactivity problem #9782

@itamarzwi

Description

@itamarzwi

Describe the bug

In the examples folder, the following Vue code is used in the Post.vue component:

<script lang="ts">
import { defineComponent } from 'vue'
import { useQuery } from '@tanstack/vue-query'

import { Post } from './types'

const fetcher = async (id: number): Promise<Post> =>
  await fetch(`https://jsonplaceholder.typicode.com/posts/${id}`).then(
    (response) => response.json(),
  )

export default defineComponent({
  name: 'PostDetails',
  props: {
    postId: {
      type: Number,
      required: true,
    },
  },
  emits: ['setPostId'],
  setup(props) {
    const { isPending, isError, isFetching, data, error } = useQuery({
      queryKey: ['post', props.postId],
      queryFn: () => fetcher(props.postId),
    })

    return { isPending, isError, isFetching, data, error }
  },
})
</script>

<template>
  <h1>Post {{ postId }}</h1>
  <a @click="$emit('setPostId', -1)" href="#"> Back </a>
  <div v-if="isPending" class="update">Loading...</div>
  <div v-else-if="isError">An error has occurred: {{ error }}</div>
  <div v-else-if="data">
    <h1>{{ data.title }}</h1>
    <div>
      <p>{{ data.body }}</p>
    </div>
    <div v-if="isFetching" class="update">Background Updating...</div>
  </div>
</template>

<style scoped>
.update {
  font-weight: bold;
  color: green;
}
</style>

But the line for queryKey holds a hidden reactivity problem. Adding the following functionality demonstrates the problem:

Image

If we enter post 1 and click the "Go to Post 2" button, the prop will change and the title will display "Post 2" but the hook will not re-fetch and the data will remain that of post 1.
The fix is to use a reactive key that will update when the prop changes, most simply - a getter function:

// queryKey: ['post', props.postId], // Before
queryKey: ['post', () => props.postId], // After

Your minimal, reproducible example

https://github.com/itamarzwi/tanstack-query-vue-example-problem

Steps to reproduce

  1. Go to post 1
  2. Click on "Go to Post 2"
  3. Title changes to "Post 2" but the hook doesn't re-fetch and the data is incorrect

Expected behavior

The examples should have code that adheres to best practices and doesn't include potential bugs

How often does this bug happen?

Every time

Screenshots or Videos

No response

Platform

  • OS: macOS
  • Browser: Safari
  • Version: 144

Tanstack Query adapter

None

TanStack Query version

5.90.5

TypeScript version

5.8.3

Additional context

I can make a pull request updating the examples if it will be accepted

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions