Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When clear a reactive array object in effect function, the array.length is not 0, all ways has a element in it. #6018

Closed
betgar opened this issue May 27, 2022 · 4 comments · Fixed by #5912
Labels
🐞 bug Something isn't working 🔩 p2-edge-case

Comments

@betgar
Copy link

betgar commented May 27, 2022

Vue version

3.2.22

Link to minimal reproduction

#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>

image

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.

@dattn
Copy link

dattn commented Sep 15, 2022

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.

@SinBirb
Copy link

SinBirb commented Aug 3, 2023

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: #3541 (comment)

@sxzz sxzz linked a pull request Sep 27, 2023 that will close this issue
johnsoncodehk added a commit to johnsoncodehk/core that referenced this issue Sep 27, 2023
yyx990803 pushed a commit that referenced this issue Oct 27, 2023
sxzz pushed a commit that referenced this issue Oct 27, 2023
@johnsoncodehk
Copy link
Member

Fixed by #5912.

@github-actions github-actions bot locked and limited conversation to collaborators Nov 11, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
🐞 bug Something isn't working 🔩 p2-edge-case
Projects
None yet
6 participants