Unexpected reactivity in shallowReactive
array
#9900
-
Given the following code: class foo {
prop1: ShallowRef<string> = shallowRef('');
prop2: string = '';
}
const obj1 = new foo();
const obj2 = new foo();
const collection = shallowReactive([obj1, obj2]);
watch(collection, (newVal, oldVal) => {
console.log('oldVal', oldVal);
console.log('newVal', newVal);
});
function updateObj1() {
collection[0].prop1.value = 'hello';
}
function addObj3() {
collection.push(new foo());
} I expect the watch to trigger the Is this a right behaviour? Since Is there a reactive way to make it the way I expect it without having to deep clone the collection? Thanks a lot for your help and time |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 2 replies
-
The documentation says:
So I'd say this is the expected behavior. Note that in your mental model you shouldn't mix the shallowness of the reactive source with the depth that the watcher observes. Those two things are unrelated. |
Beta Was this translation helpful? Give feedback.
-
I read that also, but I took the Anyway I tried adding the option I'm not sure if this is a issue or a feature... 😂 |
Beta Was this translation helpful? Give feedback.
-
True although when you
Thank you so much for doing so, I never saw the source of Vue so I wouldn't even know from where to start.
Definitively I will, because the other option is to make a deep clone of the array, which in my opnion is a dirty and expensive solution, but that will be after new year's eve 😉
I will also do so, although watching the number of current PR and the moment we are currently now I don't expect to be merged soon. Again, thank you so much @jods4 for your help and I wish you merry christmas 🎅 |
Beta Was this translation helpful? Give feedback.
shallowReactive
definitely is a reactive object as well.Just because you create shallow reactives doesn't mean there is no reactive state deeper in them. For example I always use shallow reactivity by default, because it's faster and it leads to less unwanted surprises. Yet I sometimes put reactive objects inside a shallow reactive array.
Anyway, for your case I looked at the source code.
The relevant code is https://github.com/vuejs/core/blob/main/packages/runtime-core/src/apiWatch.ts#L213
Clearly deep observation is not "the default" for a reactive object: it's forced.
I personally think this is an unfortunate limitation, it'd be useful to be able to override that default with
{ deep: …