computed which uses value from later defined composable return, used in another composable breaks reactivity
Version
3.2.33
Reproduction link
Steps to reproduce
This is a really strange edge-case but I spend a significant amount of time and could not find as solution, therefore it might actually be a bug.
- Open minimal reproduction
- Open
useFirstComposable.js
and make sure the the line forCase 2
is commented in - Run the application
- The console shows logs for
interval
andcompute computedPropExample
- Comment out
Case 2
and comment inCase 1
- Run the application
- The console only shows logs for
interval
, the computed property does not get computed anymore
The only difference (I think) between Case 1
and Case 2
ist that I'm accessing the passed ComputedRef
.
What is expected?
The computed property gets recomputed when Case 2
is active
What is actually happening?
The computed property is not recomputed when Case 2
is active
The computed property doesn't access any reactive variables in Case 1, because at the moment that you read from the computed, secondComposable
hasn't been set yet and you have this in your computed as the first line:
if (!secondComposable) return false;
So this computable will now never update again, because it doesn't have to. secondComposable
is not a reactive value, so changing it later will not trigger a re-evalutation, annd no other variables were accessed in the first read of the computed.
Thanks @LinusBorg for the explanation, it makes perfect sense!
For anyone who might find this issue with a similar problem, this can be circumvented by using a shallowRef
:
setup() {
const secondComposable = shallowRef();
const computedPropExample = computed(() => {
if (!secondComposable.value) return false;
console.log(
"compute computedPropExample",
secondComposable.value.isActive.value
);
return secondComposable.value.isActive.value;
});
useFirstComposable(computedPropExample);
secondComposable.value = useSecondComposable();
return {
computedPropExample,
};
},
https://codesandbox.io/s/vue-composable-solution-vlbglj?file=/src/components/MyComponent.vue