reactjsfetch-apiswr

Do not pass parameters/headers to cache key in SWR


I'm using SWR and passing different headers on every request. I don't want the headers to be in the cache key passed in but I don't see how I can do it with this library. The code is currently like so:

const url = `/api/holidays/${
  productDetail.subscription.subscriptionId
}/potential`;

const headers = {
  [MDA_TEST_USER_HEADER]: `${productDetail.isTestUser}`
};

const potentialHolidayStopsResponseWithCredits = useSWR(
  serialize(url, headers),
  fetcher,
  { suspense: true }
).data as PotentialHolidayStopsResponse;

I'm then triggering a global revalidation of this key using

mutate(`/api/holidays/${productDetail.subscription.subscriptionId}/potential`)

but this isn't triggering a revalidation, as I am not passing in the headers like the original fetcher key. I just want the url to be the key and be able to pass headers and parameters directly to the fetcher function, how can I do so??


Solution

  • Passing no headers to the key is possible like this as mentioned by @juliomalves.

    useSWR(url, url => fetchWithHeaders(url, headers))

    However, that's discouraged by SWR because if the headers change, then SWR will still be using the previous key and data. If that's not an issue for you, go ahead with above.

    If you want to update data when headers change, then you have two options:

    1. Include header in the key for both useSWR() and mutate(). You can use array instead of string to pass multiple arguments to fetcher:
    
    import useSWR, { useSWRConfig } from 'swr'
    const { mutate } = useSWRConfig();
    
    // and in component...
    
    const fetcherWithHeaders = (url, headers) => {
      // do something with headers and fire request
    };
    
    const headers = {
      [MDA_TEST_USER_HEADER]: `${productDetail.isTestUser}`
    };
    
    const potentialHolidayStopsResponseWithCredits = useSWR(
      [url, headers],
      fetcherWithHeaders,
      { suspense: true }
    ).data as PotentialHolidayStopsResponse;
    
    //... somewhere else:
    
    mutate([url, headers]);
    
    
    1. Pass headers into key for useSWR() , and use a bound mutate that requires no key:
    const { data, mutate } = useSWR(
      [url, headers],
      fetcherWithHeaders,
      { suspense: true }
    );
    
    // ... somewhere else in component
    
    mutate();