Subscribe on changes!

ref update does not immediately update the prop values

avatar
Mar 8th 2021

Version

3.0.7

Reproduction link

https://codepen.io/lilja-the-bold/pen/MWbPQVW?editors=0011

Steps to reproduce

Open the pen, open up the console and check the logs. Now un-comment the lines at 49 & 52(enabling the setTimeout function) and re-run the pen. Compare the logs.

What is expected?

In the first run, that the computed function to be run twice(first for the init, second for the value to be changed) and the watch event to be executed once.

What is actually happening?

The computed function is running once and the watch event is never fired.

avatar
Mar 8th 2021

This is intended. The Foo component never gets to render again and so the watcher isn't triggered. The opposite would be a problem because it will lead to wasted renders as the components would get swapped out right after. This is described in the documentation at https://v3.vuejs.org/guide/change-detection.html#async-update-queue

avatar
Mar 8th 2021

I'm not sure why it's a problem for the component to be re-rendered. Would you care to elaborate?

I would expect that if I change a reactive value that it would be changed throughout the application.

avatar
Mar 8th 2021

To further demonstrate why I think this is a problem and to give some more context of how this reflects my real world problem, I’ve written some code that is more applicable to my issue. Essentially, the logic that was inside of the outermost setTimeout inside Parent is inside the child component Foo.

// Foo

setup(props, {emit}) {
    const save = () => {
        emit(“save”, [“abc”])
    }
    const move = () => {
        if (props.myRef.length == 0) {
            /* Special logic goes here */
        }
        emit(“move”)
    }
    const saveAndMove = () => {
        save()
        move()
    }
}

// Parent

setup(props, {emit}) {
    const myRef = ref([])
    const listenToSave = (val) => {
        myRef.value = myRef.value.concat(val)
    }
    const listenToMove = () => {
        activeComponent.value = “Something other than Foo”
    }
}


As you can see in saveAndMove, I’m emiting so parent can change the props(listenToSave). The problem is that when move is executed, props.myRef.length is not 1, it’s 0. The prop has not been updated in the child component which is something I would expect to be 1, given the reactivity.

Here is another pen of this in action

avatar
Mar 8th 2021

I updated my comment 😉

We have a forum, a Discord server to ask questions where people are very active and helpful!

avatar
Mar 14th 2021

@Lilja I found that if I replace <component :is="activeComponent" :myRef="myRef" /> with <Foo :myRef="myRef" /> , it woks as expected.

So I think the key point is syntax :is . I'm new to vue, and I have no idea about it.