When clear a reactive array object in effect function, the `array.length` is not `0`, all ways has a element in it.
Vue version
3.2.22
Link to minimal reproduction
https://github.com/vuejs/core/discussions/6017
Steps to reproduce
just copy the code to HTML file, load page in browser.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>reactivity test</title>
<script src="https://unpkg.com/@vue/reactivity@3.2.36/dist/reactivity.global.js"></script>
<script>
const store = VueReactivity.ref([])
// const store = VueReactivity.reactive({
// value: []
// })
let counterForRun = 0
const effectRunner = VueReactivity.effect(() => {
console.log(`effect run times is ${counterForRun}`)
if (store.value.length > 0) {
// do some thing...
console.log(`store value is ${JSON.stringify(store.value)}`)
// clear store
// store.value.length = 0
store.value.splice(0) // trigger effect again
}
counterForRun += 1
})
let intervalTimes = 0
const intervalId = setInterval(() => {
if (intervalTimes === 2) {
clearInterval(intervalId)
// VueReactivity.stop(effectRunner)
return
}
store.value.push(intervalTimes)
intervalTimes += 1
}, 1000)
</script>
</head>
<body>
</body>
</html>
store.value.splice(0)
trigger effect callback run again, but in the effect callback, store.value.length
is not 0
.
Did I use @vue/reactivity
it in the right way ???
What is expected?
When clear store.value
, the store.value.length=0
.
What is actually happening?
Clear reactive array store
, but the store.value.length=1
, not 0
.
System Info
5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.64 Safari/537.36 Edg/101.0.1210.53
Any additional comments?
Maybe I use it in the wrong way.
I got exactly the same problem. When splicing an element out of an reactive Array, computed values are triggered too early. The item has been sucessfully removed, but the array.length is unchanged when the computed value recompution is triggered. Which causes errors when looping over that array.
This isn't really an edge-case. There should be a warning somewhere in the docs, that you should not use watch
with flush: sync
, or computedEager
for large arrays.
And that splice()
, shift()
, etc. are not atomic operations with Vue.
The JSBench example here is 10 million times slower with Proxy, on my machine: https://github.com/vuejs/core/issues/3541#issuecomment-820925456