vercel / swr

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

useSWRPages with Cursor and initialData #309

Closed tiwac100 closed 4 years ago

tiwac100 commented 4 years ago

When using initialData with Relay style cursor pagination the offset is null causing the same items to load again. Also useSWR doesn't get rerun with the new offset but uses the cached result. A strange thing happens when resizing the window: previously loaded items now render correctly and are no longer all the same.

The items prop (passed from getInitialProps higher up the tree) has the same format as the data returned from ItemsGraphQLQuery.

const Items = ({ items }) => {
  const { pages, isLoadingMore, isReachingEnd, loadMore } = useSWRPages(
    'items',
    ({ offset, withSWR }) => {
      const { data } = withSWR(
        useSWR(
          [ItemsGraphQLQuery, offset],
          (query, cursor) => request(query, { cursor }),
          { initialData: { items } }
        )
      );

      if (!data) {
        return <LoadingIndicator />;
      }

      return data.items.edges.map(edge => (
        <Item key={edge.node.id} item={edge.node} />
      ));
    },
    ({ data }) => {
      return data && data.items.pageInfo.hasNextPage
        ? data.items.pageInfo.endCursor
        : null;
    },
    []
  );

  return (
    <>
      {pages}
      {!isReachingEnd ? (<LoadMore loading={isLoadingMore} onLoadMore={loadMore} />) : null}
    </>
  );
};
hems commented 4 years ago

I got the same issue and after banging my head against the wall I did some deeper investigation on userSWR.

Turns out initialData is the initialData per fetch, so you should only provide if your offset is 0!

in my case i had to tweak to something like:

    ({ offset, withSWR }) => {
      let initialData = null

      if(!offset){
        initialData = props.initialData
      }

      const { data } = withSWR(
        // use the wrapper to wrap the *pagination API SWR*
        useSWR(['myCustomEndpoint', offset || 0], fetch, { 
          refreshInterval: 0,
          initialData
        })
      )

      ....

Once that part was figured out the rest just worked as smooth as you would expect!

I hope you have found the solution already ( :

matheusgrieger commented 4 years ago

@hems thank you so much!

hems commented 4 years ago

@hems thank you so much!

de nada Matheus ( ;

IRediTOTO commented 4 years ago

@hems Perfect, thank you so much :)

hems commented 4 years ago

@hems Perfect, thank you so much :)

thanks to the vercel guys, they rock ( :

shuding commented 4 years ago

The new pagination API has launched: https://swr.vercel.app/docs/pagination. Feel free to reopen if you are still encountering an issue!

Sokal21 commented 3 years ago

I encounter the same issue with the new useSWRInfinite. If you provide initialData the when the other pages are fetched the data does not get updated.