Kong / swrv

Stale-while-revalidate data fetching for Vue
https://docs-swrv.netlify.app
Apache License 2.0
2.15k stars 74 forks source link

How to revalidate manually and trigger data update immediately? #362

Open trojanyao opened 6 months ago

trojanyao commented 6 months ago

I'm using swrv in Vue3 + Pinia project.

In the Pinia store there's the following code:

export const useClusterStore = defineStore('cluster', () => {
  const clusters = ref()

  // Omit fetcher to use the default Fetch API
  const { data, mutate: getClusterList } = useSWRV(`${baseUrl}/cnpgs`), {
    refreshInterval: 30000,
  })
  watch(data, (newVal) => {
    clusters.value = newVal?.items
  }, { deep: true })

  return {
    clusters,
    getClusterList,
  }
})

Now, I want to revalidate manually at some time, eg. every time the clusters page show (after cluster created and navigate to this page), so there's the following code in .vue file:

<script lang="ts" setup>
const clusterStore = useClusterStore()

onMounted(() => {
  clusterStore.getClusterList()
})
</script>

But this didn't trigger revalidate and "watch" observer, also the clusters data is the old, not the latest.

Is there some logic error of my code or bug? What's the right way to revalidate manually and refresh data immediately? Thanks guys.

adamdehaven commented 6 months ago

You could also add a dynamic key (a ref) in your swrv key that can be mutated.

export const useClusterStore = defineStore('cluster', () => {
  const clusters = ref()
  const cacheKey = ref(0)

  // Omit fetcher to use the default Fetch API
  const { data, mutate: getClusterList } = useSWRV(
    () => cacheKey.value && '/cnpgs',
    () => fetch(`${baseUrl}/cnpgs`), 
    { refreshInterval: 30000 }
  )

  watch(data, (newVal) => {
    clusters.value = newVal?.items
  }, { deep: true })

  return {
    clusters,
    getClusterList,
    cacheKey,
  }
})
<script lang="ts" setup>
const { cacheKey } = storeToRefs(useClusterStore())

onMounted(() => {
  cacheKey.value++
})
</script>
trojanyao commented 6 months ago

@adamdehaven Thanks for your replay, but it still not work. cacheKey actually increased, but didn't revalidate immediately.

And there's a TS error when set () => cacheKey.value && '/cnpgs': The type '() => string | 0' cannot be assigned to the type 'IKey'. Also when I use () => Boolean(cacheKey.value) && '/cnpgs'.