how to implement useSWRinfinte with graphql query that has variables and using a cursor

Viewed 16

i have the following useSWR hook to get the first 10 links after a cursor:

const AllLinksQuery = gql`
  query allLinksQuery($first: Int, $after: String) {
    links(first: $first, after: $after) {
      pageInfo {
        hasNextPage
        endCursor
      }
      edges {
        cursor
        node {
          title
          id
        }
      }
    }
  }
`;

const fetcher = (query, {first,after}) => request('/api/graphql', query, { first, after })

const AwesomeLinks = () => {
   
    const { data, error, mutate } = useSWR( [AllLinksQuery, {first:10, after:null}] , fetcher ,  { 
        revalidateIfStale:true
    } );
 
  /** rest of the component ***/

}

its great for fetching the first 10 links, but i need to implement an infinite scroll feature, so useSWRinfinite looks like the logical thing to do. the problem is that i havent found anything in the SWR documentation on how to implement the useSWRinfinte hook with a graphql query that contains variables

with apolloClient, for example, i could just use the fetchMore function, like so:

                <button
                    onClick={() => {
                        fetchMore({
                            variables: { after: endCursor },
                            updateQuery: (prevResult, { fetchMoreResult }) => {
                                fetchMoreResult.links.edges = [
                                    ...prevResult.links.edges,
                                    ...fetchMoreResult.links.edges,
                                ];
                                return fetchMoreResult;
                            },
                        });
                    }}
                >

im new to both graphql & SWR, so any attempt to figure it out by repurposing the answers to graphql in this discussion didnt work: https://github.com/vercel/swr/discussions/601

any tip would be appreciated

1 Answers

i found the solution:

const getKey = ( index, previousData ) => {
    if( index === 0 ) return [AllLinksQuery, {first:3, after:null}]
    return [AllLinksQuery, {first:3, after:previousData.links.pageInfo.endCursor}]
}
const fetcher = (query, {first,after}) => request('/api/graphql', query, { first, after })

const AwesomeLinks = () => {
    const {  data, error, mutate, size, setSize, isValidating } = useSWRInfinite( getKey, fetcher, { 
        initialSize:1,
        revalidateIfStale: true
    } )

   /** ** /

   return ( 
      /** **/
      <button onClick={() => setSize(size + 1)}>fetch more</button>
      /** **/
   )
}

yup, that wasnt so complicated but of course i only figured it out after posting a question. hope this helps somebody!

Related