GithubHelp home page GithubHelp logo

Comments (4)

paulgrieselhuber avatar paulgrieselhuber commented on May 17, 2024 1

Fantastic, this gives me plenty to work with. Thanks!

from graphql-react.

jaydenseric avatar jaydenseric commented on May 17, 2024

There is a great way, but it it's a bit tricky to explain right now. Essentially, you use recursion to render pages. Each page has its own query, and if that page is cached it renders, if not a load button is rendered instead and recursion stops.

from graphql-react.

jaydenseric avatar jaydenseric commented on May 17, 2024

Here is an example, you can see it live at https://whimsy.art/art

import { ButtonSubmit, Heading, Scroll } from 'device-agnostic-ui';
import PropTypes from 'prop-types';
import React from 'react';
import { Header } from '../../components/Header';
import { LinkCardArtwork } from '../../components/LinkCardArtwork';
import { Meta } from '../../components/Meta';
import { PageLoader } from '../../components/PageLoader';
import {
  CARD_ARTWORK_IMAGE_HEIGHT,
  CARD_ARTWORK_IMAGE_WIDTH,
  CARD_PAGINATION_LIMIT,
  LOCALE,
  PIXEL_DENSITY,
} from '../../config';
import { useWhimsyAPI } from '../../hooks/useWhimsyAPI';

const fragmentArtworkConnectionFields = /* GraphQL */ `
  fragment queryArtworkConnectionFields on QueryArtworkConnection {
    page(
      cursor: $cursor
      limit: ${CARD_PAGINATION_LIMIT}
      ascending: false
    ) {
      hasNextPage
      cursorLast
      edges {
        node {
          id
          title
          price {
            format
            asCurrency {
              format(locale: "${LOCALE}")
            }
          }
          sold
          image {
            srcWebp: url(
              width: ${CARD_ARTWORK_IMAGE_WIDTH}
              height: ${CARD_ARTWORK_IMAGE_HEIGHT}
              devicePixelRatio: ${PIXEL_DENSITY}
              format: WEBP
              resourceHints: { preload: true }
            )
            srcFallback: url(
              width: ${CARD_ARTWORK_IMAGE_WIDTH}
              height: ${CARD_ARTWORK_IMAGE_HEIGHT}
              devicePixelRatio: ${PIXEL_DENSITY}
              format: JPG
            )
          }
        }
      }
    }
  }
`;

const queryPaginatedArtworks = /* GraphQL */ `
  ${fragmentArtworkConnectionFields}
  query($cursor: ID!) {
    artworks {
      ...queryArtworkConnectionFields
    }
  }
`;

const PaginatedArtworks = ({ page, loadedEdges = page.edges }) => {
  const operation = React.useMemo(
    () => ({
      variables: { cursor: page.cursorLast },
      query: queryPaginatedArtworks,
    }),
    [page.cursorLast]
  );

  const { load, loading, cacheValue: { data } = {} } = useWhimsyAPI({
    loadOnReload: true,
    operation,
  });

  return data ? (
    <PaginatedArtworks
      page={data.artworks.page}
      loadedEdges={[...loadedEdges, ...data.artworks.page.edges]}
    />
  ) : (
    <>
      {loadedEdges.map(({ node: { id, title, price, sold, image } }) => (
        <LinkCardArtwork
          key={id}
          artworkId={id}
          title={title}
          priceBitcoin={price.format}
          priceCurrency={price.asCurrency.format}
          sold={sold}
          imageSrcWebp={image.srcWebp}
          imageSrcFallback={image.srcFallback}
        />
      ))}
      {page.hasNextPage && (
        <ButtonSubmit onClick={load} loading={loading}>
          More
        </ButtonSubmit>
      )}
    </>
  );
};

PaginatedArtworks.propTypes = {
  page: PropTypes.shape({
    cursorLast: PropTypes.string,
    hasNextPage: PropTypes.bool.isRequired,
    edges: PropTypes.array,
  }).isRequired,
  loadedEdges: PropTypes.array,
};

const queryArtPage = /* GraphQL */ `
  ${fragmentArtworkConnectionFields}
  query($cursor: ID) {
    artworks {
      count
      ...queryArtworkConnectionFields
    }
  }
`;

const ArtPage = () => {
  const operation = React.useMemo(
    () => ({
      query: queryArtPage,
    }),
    []
  );

  const pageQueryStatus = useWhimsyAPI({
    loadOnMount: true,
    loadOnReload: true,
    loadOnReset: true,
    operation,
  });

  return (
    <>
      <Meta title="Art" description="All artworks." />
      <PageLoader
        graphqlOperationStatus={pageQueryStatus}
        renderData={(data) => (
          <>
            <Header>
              <Heading size={1}>
                {data.artworks.count} artwork
                {data.artworks.count === 1 ? '' : 's'}
              </Heading>
            </Header>
            {!!data.artworks.page.edges.length && (
              <Scroll>
                <PaginatedArtworks page={data.artworks.page} />
              </Scroll>
            )}
          </>
        )}
      />
    </>
  );
};

export default ArtPage;

from graphql-react.

jaydenseric avatar jaydenseric commented on May 17, 2024

You can see another pagination example in production here (the reviews):

https://www.bookwell.com.au/venue/kis-hair/melbourne/3000#reviews

Screen Shot 2020-09-21 at 6 44 03 pm

from graphql-react.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.