readonly(["a", "b", "c"]).includes() tracks dependencies even though array is nonreactive
Version
3.0.2
Reproduction link
https://codesandbox.io/s/vigorous-field-e0xxe?file=/src/App.vue
Steps to reproduce
readonly(["a", "b", "c"]) Collected by dependency
What is expected?
["a", "b", "c"] Should not be collected by dependency
What is actually happening?
["a", "b", "c"] Collected by dependency
You misunderstand what readonly
does. This is expected behaviour. readonly still allows for values to be collected as dependencies - it only keep you from mutating the source objects through the procxy returned by readonly
.
Maybe you are looking for markRaw()
or one of the shallow*()
APIs.
Edit: my analysis here was wrong, see below (https://github.com/vuejs/vue-next/issues/2493#issuecomment-717843604)
I'd like to ask why this design is so designed that indexes can't be collected by dependency, but by using lastIndexOf, indexof and includes. Shouldn't readonly behave consistently
setup() {
const readonlyState = readonly(["a", "b", "c"]);
effect(() => {
debugger;
readonlyState.includes("a");
});
},
so
readonly(["a", "b", "c"]) Collected by dependency
if
setup() {
const readonlyState = readonly(["a", "b", "c"]);
effect(() => {
debugger;
readonlyState[0]
});
},
readonly(["a", "b", "c"]) Should not be collected by dependency
Shouldn't readonly behave consistently
readonlyState.includes("a"); readonly(["a", "b", "c"]) Collected by dependency
readonlyState[0] readonly(["a", "b", "c"]) not be collected by dependency
Shouldn't readonly behave consistently
I'm still not sure what you are asking as your code doesn't contain any example of how different behaviour affects your use case.
However:
- in the first example, using
includes()
makes the whole array a dependency, as well as each index, as any index could be "a". - in the second example, you access one specific index, and consequently only access to that specific index is collected as a dep.
I'd like to ask why this design is so designed
readonly(["a", "b", "c"])
I mean, why don't you collect dependencies in both cases, or not
and readonlyState.includes ("a") to be collected dependency, readonlystate [0] will not be collected dependency , Any thoughts
We only collect the minimal dependencies necessary.
- in the first example, "a" could be anywhere in the array, so we have to collect the whole array as a dep.
- in the second example, we only need 1 dep for the first index of the array, because that's all that's ever read from the array.
I'm not sure how to make that clearer without an explanation of why you think we should collect more/something different.
Ah, now I get what you mean. I failed at reproducing it properly first with the snippet your provided.
Let's look into it, we might have an issue here.
You may have misunderstood the meaning
In the case of readonly(),
Why? readonlyState.includes ("a") to collect dependencies, readonlystate [0] will not collect dependencies Not consistent behavior
So thanks for being adamant here, I was wrong.
readonly on a plain value should of course not track. I usually use it on reactive values only and didn't think about it enough.
So the problem seems to be here:
We should check for isReadonly
here