nuxt-community / composition-api

Composition API hooks for Nuxt 2.
https://composition-api.nuxtjs.org
MIT License
706 stars 101 forks source link

Pinia and useFetch not working together in component #601

Open Paalt opened 2 years ago

Paalt commented 2 years ago

I am using Pinia for state management but there seem to be a compatibility issue with composition-api. Specifically the useFetch function.

The error happens when I am using useFetch in my setup function and return an imported Pinia store to the template and refreshes the page. (It works fine when navigating to the page) This will result in:

TypeError
Converting circular structure to JSON --> starting at object with constructor 'Object' --- property '_renderProxy' closes the circle 

node_modules/@nuxtjs/composition-api/dist/runtime/index.mjs
      if (val instanceof Function || val instanceof Promise) return
      data[key] = isRef(val) ? val.value : val
    }
  )
  const content = vm.$fetchState.error
    ? { _error: vm.$fetchState.error }
    : JSON.parse(JSON.stringify(data))
  if ('push' in vm.$ssrContext.nuxt.fetch) {
    vm.$ssrContext.nuxt.fetch.push(content)
  } else {
    vm.$ssrContext.nuxt.fetch[vm._fetchKey] = content

Steps to reproduce the behavior: @pinia/nuxt": "0.1.8", "@nuxtjs/composition-api": "0.31.0", "nuxt": "2.15.8",

In a component:

import { defineComponent, useFetch } from '@nuxtjs/composition-api';
import { useStore } from '@/stores/';

export default defineComponent({
  setup() {
    const store = useStore();
    const { fetch, fetchState } = useFetch(async () => {
     await fetch...
    }
    return {
      store,
    }
  }
})
<template>
<h1> {{ store.hello }} </h1>
</template>

Removing store from the return statement makes everything work fine again. So you can have both pinia store and useFetch in setup function as long as you dont use store in the template. But you often have the need for both.

P4sca1 commented 2 years ago

A workaround is to not access the store in the template directly, but to use computed properties.

P4sca1 commented 2 years ago

@danielroe See https://codesandbox.io/s/amazing-visvesvaraya-n6etwp?file=/pages/index.vue for a reproduction.

danielroe commented 2 years ago

Yes, this is an unavoidable consequence of the Nuxt 2 fetch implementation (which entails stringifying the entire component state). I'd recommend avoiding useFetch and using useAsync instead for more granular control of what is added to the Nuxt payload...

dygaomarques commented 2 years ago

@Paalt I have used the onServerPrefetch hook, and it's work for me.

ChristopherWirtOfficial commented 1 year ago

Can someone more knowledgeable explain what the downsides of using onServerPrefetch instead of useFetch? Is useFetch just capable of being either server-side or client-side, as well as adhoc instead of just server prefetch?

Basically, am I safe in assuming that if onServerPrefetch is a totally fine place for my fetch in my use case, then I'm fine using it instead of useFetch?