Best practise to ensure reactivity of prop values #14226
-
|
We have a fairly large SaaS product, and it relies on a lot of With the arrival of being able to destructure props I thought something like this would work: const { thingId } = defineProps<{
thingId: string
}>()
const enabled = computed (() => !!thingId)
const { data: thing, isLoading: isLoadingThing } = getThingQuery(thingId, { enabled })However, it turns out that the query example won't rerun when The way we've done this to date is: const props = defineProps<{
thingId: string
}>()
const thingId = computed(() => props.thingId)
const enabled = computed(() => !!thingId.value)
const { data: thing, isLoading: isLoadingThing } = getThingQuery(thingId, { enabled })I've since come across examples where const { thingId } = defineProps<{
thingId: string
}>()
const enabled = computed (() => !!thingId)
const { data: thing, isLoading: isLoadingThing } = getThingQuery(toRef(thingId), { enabled })I'm eager to understand what is the best approach for handling this example? Note The query example used accepts a reactive value which is then passed to TanStack Query, which will rerun the query whenever the value changes. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
|
When using prop destructuring for For example, with code like this: getThingQuery(thingId)The compiler will rewrite it to something like this: getThingQuery(props.thingId)Importantly, that is passing the current value of As you noted, you can use const t = computed(() => props.thingId)
getThingQuery(t)That's fine, but // toRef with a function, similar to `computed`
const t = toRef(() => props.thingId)
getThingQuery(t)Or alternatively: // toRef with two arguments, passing the property name as a string
const t = toRef(props, 'thingId')
getThingQuery(t)We actually don't need a ref at all, we could pass a getter function directly to getThingQuery(() => props.thingId)In all cases, the key thing to appreciate is that it delays the reading of the property value. This gives Back to destructuring props, you can also use a const { thingId } = defineProps<{
thingId: string
}>()
const t = computed(() => thingId)
getThingQuery(t)This looks redundant, but remember that Again, we could use const { thingId } = defineProps<{
thingId: string
}>()
const t = toRef(() => thingId)
getThingQuery(t)As previously, it also isn't necessary to use const { thingId } = defineProps<{
thingId: string
}>()
getThingQuery(() => thingId)
The section I've linked is the one most directly relevant to your question, but I suggest reading the page from the top as there's some important context given elsewhere on the page and that section may not be as clear if you haven't read the rest of it. To address one other point you raised, you suggested code like this for using const { data: thing, isLoading: isLoadingThing } = getThingQuery(toRef(thingId), { enabled })That won't really get you what you want. Writing See also https://vuejs.org/guide/components/props.html#passing-destructured-props-into-functions, which mentions many of the same ideas that I've discussed here. |
Beta Was this translation helpful? Give feedback.
When using prop destructuring for
thingId, the compiler will rewrite uses ofthingIdtoprops.thingId. If something wouldn't work withprops.thingIdthen it won't work with props destructuring either.For example, with code like this:
The compiler will rewrite it to something like this:
Importantly, that is passing the current value of
props.thingIdtogetThingQuery. If that value changes later,getThingQuerywon't know anything about it.As you noted, you can use
computedto get around this problem when usingpropsexplicitly:That's fine, but
computedcomes with some extra intern…