parent and child with watchEffect and emits causing endless loop #13501
-
I have a parent component that contains a child component. When the child component goes to make an API call, I want to show a loading spinner overlay in the parent. But the child makes the API call using The example below is simple, but in the real case, watchEffect would be tracking many objects. The parent is a container, and child could be one of many component types, so looking for a generalizable way to do this. I tried to wrap the mutation of the loading counter with How can I achieve my goal? Parent component: <template>
<overlay v-show="is_loading">
<childcomponent @start-loading="onStartLoading" @finish-loading="onFinishLoading" />
</overlay>
</template>
<script setup>
const loading_counter = ref(0);
const is_loading = computed(() => loading_counter.value > 0);
function onStartLoading(){
loading_counter.value++;
}
function onFinishLoading(){
loading_counter.value--;
}
</script> child component: <script setup>
const loaded_data = ref(null);
const dependency = ref("some_data");
watchEffect(async () => {
emit("start-loading");
loaded_data.value = await API.call(dependency.value);
emit("finish-loading");
});
</script> |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
The code you provided contains some small mistakes, where you're using There are various ways to write the code to avoid the tracking problem, depending on whether you want to apply the fix in the parent or the child. Based on what you wrote, I'm assuming you'd prefer to fix this in the parent. e.g. Something like this: import { nextTick } from 'vue'
const loading_counter = ref(0);
const is_loading = computed(() => loading_counter.value > 0);
async function onStartLoading(){
await nextTick()
loading_counter.value++;
}
async function onFinishLoading(){
await nextTick()
loading_counter.value--;
} There's not really anything special about |
Beta Was this translation helpful? Give feedback.
emit
is synchronous, with any handlers being run immediately. This can lead to properties being tracked fromwatchEffect
. This is a common source of problems and #6688 aims to fix that, though it remains unclear whether that will be merged.The code you provided contains some small mistakes, where you're using
loading_counter
instead ofloading_counter.value
. If any of those mistakes are also present in your original code then they might be compounding the problem.There are various ways to write the code to avoid the tracking problem, depending on whether you want to apply the fix in the parent or the child. Based on what you wrote, I'm assuming you'd prefer to fix this in the parent.
e.…