N
Nuxt3mo ago
ludgart

Component is already mounted, please use $fetch instead

Hello, I'm struggling with the following error message:
Component is already mounted, please use $fetch instead
Component is already mounted, please use $fetch instead
The warning messages appear only when the page navigate again. Example: 1.) First page load - fine 2.) Switching to the other page - fine 3.) Back to the first page - warning. Inside my setup function, I tried the following code to fetch the data from the server:
const { data } = await useFetch(`/api/test`);
const { data } = await useFetch(`/api/test`);
same for:
const { data} = await useAsyncData(() => $fetch(`/api/test`, { headers }));
const { data} = await useAsyncData(() => $fetch(`/api/test`, { headers }));
Nuxt version: 3.15.0 with Nitro 2.10.4 How can I solve the issue?
5 Replies
kapa.ai
kapa.ai3mo ago
Hi @ludgart. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- This is a common issue in Nuxt 3 related to data fetching composables. Let's break down the problem and provide a solution based on the knowledge sources. The warning message you're seeing is intended to prevent unnecessary refetching of data when a component is already mounted. This behavior was introduced as a feature in Nuxt 3 to optimize performance and avoid duplicate network calls. According to the Nuxt documentation on data fetching (https://nuxt.com/docs/getting-started/data-fetching#lazy), by default, data fetching composables like useFetch and useAsyncData will wait for the resolution of their asynchronous function before navigating to a new page. This can cause issues when navigating back to a page that has already been mounted. To solve this issue, you have a few options: 1. Use the lazy option: You can add the lazy option to your useFetch or useAsyncData call. This will allow the navigation to happen immediately and the data will be fetched in the background.
const { data } = await useFetch('/api/test', { lazy: true });
const { data } = await useFetch('/api/test', { lazy: true });
Or for useAsyncData:
const { data } = await useAsyncData(() => $fetch('/api/test', { headers }), { lazy: true });
const { data } = await useAsyncData(() => $fetch('/api/test', { headers }), { lazy: true });
When using the lazy option, you'll need to handle the loading state manually using the pending or status value returned by the composable. 2. Use useLazyFetch or useLazyAsyncData: These are convenient methods that Nuxt provides to achieve the same result as using the lazy option:
const { data } = useLazyFetch('/api/test');
const { data } = useLazyFetch('/api/test');
3. Use a unique key for each fetch: If you want to refetch the data on each navigation, you can use a unique key for each fetch. This will force Nuxt to make a new request each time:
const { data } = await useFetch('/api/test', {
key: Date.now()
});
const { data } = await useFetch('/api/test', {
key: Date.now()
});
4. Use $fetch directly for client-side fetching: If you don't need server-side rendering for this particular data, you can use $fetch directly in a method or a watch effect:
const data = ref(null);

onMounted(async () => {
data.value = await $fetch('/api/test');
});
const data = ref(null);

onMounted(async () => {
data.value = await $fetch('/api/test');
});
Remember that using $fetch directly will not provide the same benefits as useFetch or useAsyncData in terms of SSR and hydration. These solutions should help you resolve the warning and ensure that your data is fetched correctly when navigating between pages. Sources: Nuxt Data Fetching Documentation (https://nuxt.com/docs/getting-started/data-fetching#lazy) Stack Overflow: Nuxt - Component is already mounted, please use $fetch instead (https://stackoverflow.com/questions/78734355) ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai3mo ago
<@346292320637026304> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
ludgart
ludgartOP3mo ago
I already tried with the key option. Lazy option is not the way I would like to go. Data should be first rendered on server side.
Bootsmann
Bootsmann3mo ago
hi @ludgart do you have a ss or copy of the full setup function? or can you make a quick reproduction of this, maybe i can help.
ludgart
ludgartOP2mo ago
Hello, thanks for reaching me. Sure, I can provide you an example of my setup function. It's nearly the same, as I already posted. Example setup()
async setup() {
definePageMeta({
auth: true,
layout: 'client-layout'
});

const internationalEuro = new Intl.NumberFormat('de-DE', {
style: 'currency',
currency: 'EUR'
});

const { status: exampleStatus, data: exampleData } = await useFetch('/api/example');
const { status: testStatus, data: test} = await useFetch('/api/user/test');

return {
exampleStatus,
exampleData,
testStatus,
test,
internationalEuro
};
},
async setup() {
definePageMeta({
auth: true,
layout: 'client-layout'
});

const internationalEuro = new Intl.NumberFormat('de-DE', {
style: 'currency',
currency: 'EUR'
});

const { status: exampleStatus, data: exampleData } = await useFetch('/api/example');
const { status: testStatus, data: test} = await useFetch('/api/user/test');

return {
exampleStatus,
exampleData,
testStatus,
test,
internationalEuro
};
},

Did you find this page helpful?