Next.js Discord

Discord Forum

How to get useSWRInfinite to work with multiple query parameters?

Unanswered
Arboreal ant posted this in #help-forum
Open in Discord
Arboreal antOP
Hi all,

I'm attempting to get useSWRInfinite to work with multiple query parameters.

Here's my current attempt:

type KeyGetterFn = (index: number, previousPageData: Steps | null) => string;

const getKey = (queryParams: {
  limit?: number;
  offset?: number;
  organisationId?: string;
  search?: string;
  stepStatuses?: StepStatusEnum[];
}): KeyGetterFn => {
  return (index: number, previousPageData: Steps | null): string => {
    const offset = index * (queryParams?.limit ?? 10);

    const encodedQueryParams = encodeQueryParameters({
      ...(queryParams ?? {}),
      offset,
    });

    return `${baseUrl}/steps?${encodedQueryParams}`;
  };
};

export const useStepsGetInfinite = (
  {
    queryParams,
  }: {
    queryParams: {
      limit?: number;
      offset?: number;
      organisationId?: string;
      search?: string;
      stepStatuses?: StepStatusEnum[];
    };
  },
  requestInitArgs?: RequestInit,
  swrOptions?: SWRInfiniteConfiguration,
) => {
  const router = useRouter();

  const { data, error, isLoading, mutate, isValidating, size, setSize } = useSWRInfinite<Steps>(
    getKey(queryParams),
    () =>
      stepsGetFetch({ queryParams, ...requestInitArgs }).then(async (response) => {
        if (response.status === 401) {
          router.push(`${process.env.NEXT_PUBLIC_FE_API_BASE_URL}/auth/sign-in` as Route);
          return;
        }

        const resBody = await response.json();

        if (!response.ok) {
          console.log({
            resBody,
            stringified: JSON.stringify(resBody),
            errorJson: new Error(resBody),
            errorString: JSON.stringify(resBody),
          });
          throw new SwrError(resBody.message, resBody.statusCode);
        }

        return resBody;
      }),
    swrOptions,
  );

  return {
    data,
    isLoading,
    isError: !!error,
    error,
    mutate,
    isValidating,
    size,
    setSize,
  };
};

2 Replies

Arboreal antOP
If I log the index and offset values from the getKey fn I see them both at 0, and the keys that are output look the same, but the returned array of steps has duplicate entries in it. It's just the first 10 items repeated twice. Shouldn't the key prevent these duplicates?
Arboreal antOP
I tried using an array for the key instead of the full string but still no luck. It was adding the first return every time.

For now I've created my own custom hook to do the fetching using normal useSWR and implement infinite scrolling myself in state which seems to work well enough. Would still be nice to not use a home rolled solution though as I'm sure there are issues.