SvelteStack / svelte-query

Performant and powerful remote data synchronization for Svelte
https://sveltequery.vercel.app
MIT License
813 stars 31 forks source link

using same query in multiple files #95

Open Nisthar opened 2 years ago

Nisthar commented 2 years ago

I have two components: UserHome.svelte and UserProfile.svelte.

I want to query users posts when the user navigates to UserHome.svelte. But i want the data to be stored in cache and when the user navigates to UserProfile.svelte it should have access to the cached data. How can i do this?

sillvva commented 2 years ago

You should be able to just use the same query key and fetcher function. If the data is still cached, it will return the results that were previously cached with that key. To avoid background re-fetches, update your cacheTime and staleTime defaults.

Caching Info: https://sveltequery.vercel.app/guides/caching Query Options Reference: https://sveltequery.vercel.app/reference/useQuery

const queryResult = useQuery(queryKey, queryFn?, {
   cacheTime: 15 * 60 * 1000, // 15 minutes
   staleTime: 10 * 60 * 1000 // 10 minutes
 })

The difference between cache time and stale time is this:

Nisthar commented 2 years ago

You should be able to just use the same query key and fetcher function. If the data is still cached, it will return the results that were previously cached with that key. To avoid background re-fetches, update your cacheTime and staleTime defaults.

Caching Info: https://sveltequery.vercel.app/guides/caching Query Options Reference: https://sveltequery.vercel.app/reference/useQuery

const queryResult = useQuery(queryKey, queryFn?, {
   cacheTime: 15 * 60 * 1000, // 15 minutes
   staleTime: 10 * 60 * 1000 // 10 minutes
 })

The difference between cache time and stale time is this:

  • Cached data is returned immediately when the component is mounted.
  • If the data is stale, it will trigger a background re-fetch and update the data.

I can only seem to access it on the same page.

const getMyPostsRequest = useQuery(
        'getMyPosts',
        async () => {
            const myPosts = await api('GET', 'profile/myPosts', null, {
                currentSession: $session
            });
            return myPosts?.data;
        },
        { staleTime: Infinity }
    );

i can access this data in the same component using useQueryClient().getQueryData('getMyPosts') but if i use it in another page, it is always undefined. I prefer not to import the fetcher function in every components.

multiplehats commented 1 year ago

Here's how I do it @Nisthar .

// $lib/queries.ts

export const useWatchlistItems = () => {
  return useQuery(
    ['watchlist', 'menuList'],
    async () => {
      const { data, error } = await getWatchlist({ orderByPrimaryKey: true });
      if (error) throw error;
      return data;
    },
    {
      refetchOnWindowFocus: false
    }
  );
};
<script lang="ts">
// some-page.svelte
import { useWatchlistItems } from '$lib/queries;

$: queryRes = useWatchlistItems();

// Do whatever..
</script>

{#if $queryRes.isLoading}
    <span>Loading...</span>
{:else if $queryRes.isError}
    <span>Error: {$queryRes.error.message}</span>
{:else if $queryRes.data}
    <div>{JSON.stringify($queryRes.data)}</div>
{/if}
<script lang="ts">
// some-componen.svelte
import { useWatchlistItems } from '$lib/queries;

$: queryRes = useWatchlistItems();

// Do whatever..
</script>

{#if $queryRes.isLoading}
    <span>Loading...</span>
{:else if $queryRes.isError}
    <span>Error: {$queryRes.error.message}</span>
{:else if $queryRes.data}
    <div>{JSON.stringify($queryRes.data)}</div>
{/if}