vercel / swr

React Hooks for Data Fetching
https://swr.vercel.app
MIT License
30.64k stars 1.22k forks source link

useInfinite calling getKey with undefined pageIndex and previousPageData beta 9 #1325

Closed from-nibly closed 3 years ago

from-nibly commented 3 years ago

Bug report

Description / Observed Behavior

When using beta 9 and calling useSWRInfinite((pageIndex, previousPageData) => ...dostuff) both parameters are showing up as undefined.

Expected Behavior

According to the types this should always return a number and the previous data or null.

Repro Steps / Code Example

I'm not sure what part of my code is causing this but I am using a provider.

            <SWRConfig
              value={{
                fetcher: axiosFetcher(client),
                cache: memoryCache,
              }}
            >
export const axiosFetcher =
  (client: AxiosInstance) =>
  async (url: string): Promise<State<any>> => {
    const resp = await client({
      method: 'get',
      url,
    });

    return createState(resp.data);
  };

export const { cache: memoryCache, mutate } = createCache(new Map());
useSWRInfinite<State<Pagination<Gift>>>(
    (pageIndex, previousPageData, ...args: any[]) => {
      return getKey(
        pageIndex,
        previousPageData,
        pageSize,
        orgName,
        campaignID,
        search
      );
    }
  );

Additional Context

SWR version. 1.0.0-beta.9 / 1.0.0-beta.8

I'm guessing something is going wrong with the middlewares. I think it's just not calling the infinite middleware.

My suspicion comes from the fact that if I insert pageIndex = pageIndex ?? 0 into the getKey function it returns data, but that data is not an array. (acting like a normal useSWR call).

Trying to debug is crazy as well since all of the js in the package is minified. I think there was some function in the stack that had the middlewares set to something but I have no idea at what point.

It's possible that the provider config isn't being merged properly with the config that is adding the middleware with withMiddleware

from-nibly commented 3 years ago

Note: I have already tried omitting the cache from the config.

shuding commented 3 years ago

To confirm, both pageIndex and previousPageData are undefined in your case right?

MatteoGauthier commented 3 years ago

In my case previousPageData, I have the replicated the example in the docs

ejossev commented 3 years ago

Hi, just experiencing the same issue:

const getKey = (pageIndex, previousPageData) => {
  console.log("getKey called for index " + pageIndex + " " + previousPageData)
  const addr = window.ethereum.selectedAddress
  if (previousPageData && !previousPageData.length) return null 
  const start = startIndex + pageIndex * pageSize;
  const end = start + pageSize - 1
  return {addr, start, end}
}

const fetcher = async (addr, start, end) => {
  console.log("Fetcher called with params ",  (addr, start, end))
  return await getNftsByRange(start, end, addr);
}

export default function Home() {
  const { data, size, setSize } = useSWRInfinite(getKey, fetcher, {revalidateAll: true, initialSize: 1})
  (...)

}

In the console, I can see:

getKey called for index undefined undefined
Fetcher called with params  {addr: undefined, start: undefined, end: undefined}
HeavenlyEntity commented 3 years ago

Version of 1.0.1 same behavior with useSWRInfinite()

To note this issue is occurring on latest release v1.0.1. useSWRInfinite first arg as a type function in example of getKey() passes pageIndex & previousPageData as undefined. Downgrade to v0.5.6 this will fix the issue.

You can test this in their codesandbox by changing the version in package.json to v1.0.1 then to v0.5.6 then destruct the import.

ninpeng commented 3 years ago

I have same problem.

shuding commented 3 years ago

OK, now I know why this is happening and why I cannot reproduce it. Since SWR 1.0.0, you have to import useSWRInfinite from 'swr/infinite' instead of 'swr':

- import { useSWRInfinite } from 'swr'
+ import useSWRInfinite from 'swr/infinite'

It's mentioned here: https://swr.vercel.app/blog/swr-v1#update-useswrinfinite-imports as well as the docs.