Subscribe on changes!

shallowRef value with object/array as the return of a computed passed as a prop to a child component does not update with triggerRef

avatar
Apr 5th 2023

Vue version

3.2.47

Link to minimal reproduction

https://sfc.vuejs.org/#eNqNU01v2zAM/SuELnVQx97ZSYoF66WnFdtx3sGxlUSpLGmSnDYI/N9HUbaTtNsw+GB9kI/k03tntjYmO3acFWzpaiuMB8d9Zx5KJVqjrYcveyEb2FrdQsmynLYho2QLmILOYPk2hVq3pvO8gT4m3GHc3WKK+ro58NpfsOI+OzjEKhUgXK2Vww585TmsJrgkmcHqAc6lKn2MOFayCxEDAiVkdDgAASYrpyXPpN4lJXuuLFe+KFkac2cYF+AsDmtVPMOjPpwv88gEcoAbz1sjER53AMtGHGmBy03nvVbwuZaiflmVbOilMw1Gfw8dJbOSDdEA66aBp8chN4/JI1TkuKAxEIn+mLqMbMfKeSy9zKeGWMoisfO2MsiiVviKSBLOP1wgsUWgLRQpGT1agYu998YVee62dXjJg8u03eW4ymynvGh5xl0731j96ril50mvMHI8PHI7R0Ibbrn9F+a70A+4AbZH2nGUSQw4xKQqb8Vux+23IC63r6TUr7ge5TWMRE8puQfRoCQ+0fZWSJfU5MfPWdBt+PgbVWn4tuokVgvN7BCGslByA3GDROiU1NUTGzfvPMZeCTEzndsnorm/D5oKl5dhEoqL5wGtXyABk7P+7sXzB4eNFETNj3Mbq43DuXE0ofhz2CXUIdVFSYA/Gfyvra1OKU74qxOWNwW2iLaijmJzI+BYlsb9ozPfG46mIb9RM9GiI+hE6tXd/7ivk6NjpIDjfKstugU5TvHp32Yg1G2jJYMXfsIQvL1y4tMjMnAOaulRe9GPUgwuoxLXJut/A5Fovi0

Steps to reproduce

  1. Create a parent component with a computed that returns a shallowRef.value (array/object)
  2. Pass the computed as a prop to a child component
  3. Modify the array or object (nothing happens, as its a shallowRef).
  4. Use triggerRef to trigger an update.
  5. The computed in the parent will update.
  6. The prop in the child won't as gets the same reference to the array/object

What is expected?

Since triggerRef should trigger updates, it should trigger the prop of the child component to update as well.

What is actually happening?

On triggerRef the computed in the parent component updates, yet the prop in the child does not.

System Info

No response

Any additional comments?

Question is, is this by design? Because the fact that it passes the same reference and therefore doesn't update seems correct. However I'm forcing a trigger so I would expect it to update. If you a normal ref within the computed it always updates. So for the time being im using a normal ref in combination with markRaw.

My use case is any array, which receives e.g 50 updates at once. I add the 50 updates to array and only trigger the ref update once.

avatar
Apr 5th 2023

Question is, is this by design?

It is.

However I'm forcing a trigger so I would expect it to update.

  • The code that depends on the ref does update: App.vue
  • Child.vue does not depend on this ref. it only receives a plain object as props and has no idea that this value came from a ref that was triggered.

So triggering a ref simply won't allow you to do what you want it to.

My use case is any array, which receives e.g 50 updates at once. I add the 50 updates to array and only trigger the ref update once.

If you do those 50 updates synchronously, it will only trigger once. There's different ways to achieve that. Ask the community on chat.vuejs.org or the "Discussions" section of this repo.

avatar
Apr 5th 2023

Question is, is this by design?

It is.

However I'm forcing a trigger so I would expect it to update.

* The code that depends on the ref does update: `App.vue`

* `Child.vue` does not depend on this ref. it only receives a plain object as props and has no idea that this value came from a ref that was triggered.

So triggering a ref simply won't allow you to do what you want it to.

My use case is any array, which receives e.g 50 updates at once. I add the 50 updates to array and only trigger the ref update once.

If you do those 50 updates synchronously, it will only trigger once. There's different ways to achieve that. Ask the community on chat.vuejs.org or the "Discussions" section of this repo.

Thanks for the quick reply, I've managed my way around it with ref + markRaw for the items. Since ref.value is reactive.

avatar
Jun 30th 2023

If you make a shallow copy of the array, this will work as a workaround

const originalArray = shallowRef([]); const array = computed(() => originalArray.value.slice());