infinite scroll with get static props and grapql not working

Viewed 79

I'm working on a project with pokeapi graphql and I made a infinite scroll component that loads more pokemon when you scroll the page. I wanted to have the first 48 pokemons pre loaded with static generation.

So I have my index page the following code:


const Home = ({ fallback }): JSX.Element => {
  return (
    <div>
      <SWRConfig value={fallback}>
        <PokemonList />
      </SWRConfig>
    </div>
  );
};


export const getStaticProps: GetStaticProps = async () => {
  const url =
    'species: pokemon_v2_pokemonspecies(order_by: {id: asc}, limit: 24, offset: 0)';
  const pokemonList = await getPokemonListData({
    url,
  });

  return {
    props: {
      fallback: {
        'species: pokemon_v2_pokemonspecies(order_by: {id: asc}, limit: 24, offset: 0)':
          pokemonList,
      },
    },
    revalidate: 60 * 60 * 24, // 24 hours
  };
};

And I use this custom hook for the data:

import getPokemonListData from '@requests/getPokemonListData';
import useSWRInfinite from 'swr/infinite';

interface IUsePokemonListParams {
  limit?: number;
}

interface IUsePokemonListReponse {
  pokemonList: IBasicPokemonInfo[][];
  isLoading: boolean;
  size: number;
  setSize: (
    size: number | ((_size: number) => number),
  ) => Promise<IBasicPokemonInfo[][]>;
}

export default function usePokemonList({
  limit,
}: IUsePokemonListParams): IUsePokemonListReponse {
  const getKey = (pageIndex, previousPageData) => {
    if (previousPageData && !previousPageData.length) return null; // reached the end
    return `species: pokemon_v2_pokemonspecies(order_by: {id: asc}, limit: ${limit}, offset: ${
      pageIndex * limit
    })`;
  };

  const { data, error, size, setSize } = useSWRInfinite(getKey, url =>
    getPokemonListData({ url }),
  );

  return {
    pokemonList: data,
    isLoading: !error && !data,
    size,
    setSize,
  };
}

on my list component I use the custom hook and list the data in another component:

const PokemonList = (): JSX.Element => {
  const loader = useRef(null);
  const { pokemonList, setSize } = usePokemonList({ limit: 24 });

  useController({ loader, setSize }); // this is my infinite scroll logic, I set the size when I reach the page limit

  useEffect(() => {
    document.body.className = 'initial';
  }, []);

  return (
    <>
      <ol className={styles.cardContainer}>
        <>
          {pokemonList.map((list, index) => (
            <Fragment key={index}>
              {list.map(pokemon => (
                <li key={pokemon.id}>
                  <Pokemon
                    id={pokemon.id}
                    name={pokemon.name}
                    types={pokemon.types}
                    image={pokemon.image}
                  />
                </li>
              ))}
            </Fragment>
          ))}
        </>
      </ol>
      <div ref={loader} />
    </>
  );
};

However, when I call the custom hook on my list component, for some reason the data returned from the hook, in this case the "pokemonList", is undefined and the request has to be made again. Is there something that I'm missing?

1 Answers

You have a mistake in your SWRConfig. Instead of <SWRConfig value={fallback}> you should have <SWRConfig value={{fallback}}>

Related