Skip to content

triggerRef fails when target is an array #12427

@ilyary

Description

@ilyary

Vue version

3.5.6

Link to minimal reproduction

https://play.vuejs.org/#eNqVU8tu2zAQ/JUtL5IBVW7QnlzZSFsYaHtIi6RAD2UPsrySlVIkwYdiQNC/d0klthMEDnIRxJnZ4SyXHNgnrfPeI1uwwlam1Q4sOq9XXLadVsbBAAbrjD5l5doeM3DqOgB3pat267rGyhFm2qZBQ8QItVEdJOSZcMllpaR10NkGlsEoTb6iEAp+KyO2b5LZUVIr00XNtE86gLdoFrQ/dmUrFvAnKS/LvFJdkkGyudzE378wwjj7eLSJ4ivfbWIaMoxx0+CeB8M8CjJ4F4pOekjTGSxXMHAJEJyUwFyoJn3sl/el8BhK7zc9Nv5EOdGPUt2QWDZnUyUXyWtyHRxfzHVQBrqYT6OmIdPCYadF6ZBWAMXuYjUMcV7jWMxpFdFWau+gf9upLYolZ8RzBnMii/lJPcuYs5Sybpv81ipJtyoG54xmpVuB5od2LXXBGQ02MIEr6ULcfY+YMx6zB7zaYfXvGfzW7gPG2U+DdHY9cnbgXGkadBO9vrnCPf0fSErvBanPkNdIJ+xDxkn22cstxT7RxbTf4tugE/1l13uH0j40FYIG5Rj1nNEz+HKm9WPc9/mHWEcTZON/Pog4cQ==

Steps to reproduce

const form = reactive({ user: { email: ['a@a.com', 'b@b.com'] } });

const emailNumberRef = toRef(form.user.email, 0);
watchEffect(() => {
  console.log(emailNumberRef.value);
});

triggerRef(emailNumberRef); // <-- FAILS
/*
@vue/reactivity/dist/reactivity.cjs.js:1487
    ref2.dep.trigger({
             ^

TypeError: Cannot read properties of undefined (reading 'trigger')
*/

const emailStringRef = toRef(form.user.email, '1'); // <-- TS is not happy
watchEffect(() => {
  console.log(emailStringRef.value);
});

triggerRef(emailStringRef); // <-- WORKS FINE

On The SFC playground it fails silently. No effect is called for number prop, but it works fine for string prop

What is expected?

triggerRef triggers effects for a reference with an integer key

What is actually happening?

triggerRef fails on a reference with an integer key

System Info

System:
    OS: macOS 14.4.1
    CPU: (8) arm64 Apple M1
    Memory: 66.09 MB / 16.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 20.12.2 - ~/.nvm/versions/node/v20.12.2/bin/node
    npm: 10.5.0 - ~/.nvm/versions/node/v20.12.2/bin/npm
    pnpm: 9.10.0 - ~/.nvm/versions/node/v20.12.2/bin/pnpm
  Browsers:
    Chrome: 130.0.6723.117
    Safari: 17.4.1

Any additional comments?

it happens because Proxy index gets converted to string.

So, here

track(target, TrackOpTypes.GET, key)
the property starts being tracked with a string key but later on is referenced with a number key
const depMap = targetMap.get(object)

Consider converting string key to number for arrays when tracking

Metadata

Metadata

Assignees

No one assigned

    Labels

    🔨 p3-minor-bugPriority 3: this fixes a bug, but is an edge case that only affects very specific usage.has workaroundA workaround has been found to avoid the problemscope: reactivity

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions