Skip to content

Reactivity not triggering update #10046

@nurdism

Description

@nurdism

Vue version

3.4.6

Link to minimal reproduction

https://play.vuejs.org/#eNqNVFtr2zAU/isHM6gzHLujYw8h6bqOPnTQdXTb0zKoah8nTmXJSHLSEfzfdyT5lrS7hECUc/3Ody774ENVxdsag1kw16kqKgMaTV0BZ2K1WAZGL4PzpVoKgKKspDKwBykuMZcKv4tS1sJEJLixD8wiUJhHYFSxWqG6s+9UllVNKmggV7KEE0p2YgP6oKkUmlIaZhAWsPdCJzb4ZGY2XriHXMoZnEIz8fpm7FuQpRKMW/fBb/Dx1t4jr0VqCilsjWHGDJvMYCuLbEicJEAA4Sw+g8LATqpHgr6pKU9eCIxI8RYKDQyEhJV837ndPmwwNfEj/tI+bkwEXbF0HYYkm8DifEgBQMRwa25RdPDjFnoE5BCBDfKDXj/bkqno/jUiSUuOMZer8N46zODV3v5SctlEPTNWfJymNen5erV3PejVW8ZrdEb3E0vKruAcKBFoViKIunxApQdiwbfw0J06cpzWhjJrIpC+QppuUgqxAiagrgg9dhGHKQoPgjs8XRDGtfxHpFH//cR0WBb9cIaha9ELNTjSvTPHdthIQb6i5twr+vFvw/SdHllTq6/bf10yan47pTfMrOOcS6lC91RMZLIks9fw5pQ+E2p+5J7dAoxgHW3jMww5+BmjzJPxEKYcmeox9Sb9uB1nmif+Prhr4AQGy4oTY+19mGfF9nxYwH4Z7RRB08wTq/eRDjyDKPCnZVqyKt5oKegY7W3EZaugG0QB2+EPaD/t/2WwNqbSsyRJM0FuGfJiq2KBJhFVmVyQWaKIkKLEKbF5QZsbvyMM2ozFMepy+qDkTqOiIMsgGqVJSLhFNVUoMlSo/jftkds49ZHqWXo/sKIhUowmAvNidUSJndmCo7qt7CU7pIZxLnefnMyoGvta0jWmjy/IN/rJ1/RFoUM2qt8wtULj1VdfP1MjR8pSZjVv2/AH5R3ScaotRm92WYuMYI/sHNpr12Fa22/66smg0F1RFqhjw9m7fnz8S+kDXLrdPYvNb8Z1VWc=

Steps to reproduce

I'm not entirely sure what the issue is, but this code worked in 3.3 and no longer works in 3.4.

<script setup lang="ts">
  import { onBeforeUnmount, onMounted, ref, triggerRef, computed } from 'vue'

  const state = {
    context: ref({ foo: 0 })
  }
  const internal = { context: { foo: 0 } }

  function set(data): void {
    // vue 3.3 it worked just fine, 3.4 is a no go?
    Object.keys(data).forEach((key) => {
      Reflect.set(internal.context, key, data[key])
    })
    
    console.log(`data: ${data.foo}, internal: ${internal.context.foo}, context: ${state.context.value.foo}`) // will log same numbers

    state.context.value = internal.context // this is not triggering an update
    triggerRef(state.context) // this is also not triggering an update
  }

  const context = computed(() => state.context.value)

  let interval = null
  onMounted(() => {
    interval = setInterval(() => set({ foo: Math.floor(Math.random() * 10000) }), 1000)
  })

  onBeforeUnmount(() => {
    if (interval) {
      clearInterval(interval)
    }
  })

</script>

<template>
  <div>context: {{ context.foo }}</div>
</template>

The code example above shows that an update is not triggered when the state changes. I discovered a few things: if the ref is a const context = ref({ foo: 0 }) and is not nested in an object, an update gets triggered. And if I create a new object instead of mutating the original object it will fire an update. The state does change; you can see it in the log, but it is not reflected in the UI.

What is expected?

An update to be triggered when I change the state.

What is actually happening?

An update is not being triggered, the state is changing, but the update is not triggered .

System Info

System:
    OS: Linux 5.15 Debian GNU/Linux 12 (bookworm) 12 (bookworm)
    CPU: (12) x64 AMD Ryzen 5 3600X 6-Core Processor
    Memory: 53.92 GB / 62.71 GB
    Container: Yes
    Shell: 5.2.15 - /bin/bash
  Binaries:
    Node: 20.10.0 - /usr/local/share/nvm/versions/node/v20.10.0/bin/node
    Yarn: 1.22.19 - /usr/bin/yarn
    npm: 10.2.3 - /usr/local/share/nvm/versions/node/v20.10.0/bin/npm
    pnpm: 8.14.0 - /usr/local/share/nvm/versions/node/v20.10.0/bin/pnpm
  npmPackages:
    vue: ^3.4.5 => 3.4.6

Any additional comments?

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions