pradel / stacks-ceramic-demo

A simple todos app built with Stacks and Ceramic ComposeDB
MIT License
0 stars 0 forks source link

usePaginationFragment #5

Open dabuchera opened 1 year ago

dabuchera commented 1 year ago

Hi Léo

Sorry for asking again smth. Running into the following challenge. I want to use the usePaginationFragment from react-relay. For that the type has to implements Node. Similar to your runtime schema the MYTYPEConnection is not working with @refetchable since not implements Node

Do you have any idea how to solve that? Is there a possibility to do that in the basic model?

In detail my component looks like that:

import React, { useState } from 'react';
import { useLazyLoadQuery, graphql } from 'react-relay';

const MaterialpassportFragment = graphql`
  fragment Materialpassports_materialpassport on Materialpassport {
    id
    name
    completed
  }
`;

const materialpassportIndexFragment = graphql`
  fragment Materialpassports_materialpassportIndex on MaterialpassportConnection
  @refetchable(queryName: "MaterialpassportsPaginationQuery")
  {
    edges {
      node {
        ...Materialpassports_materialpassport
      }
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
`;

const materialpassportQuery = graphql`
  query MaterialpassportsPaginationQuery($count: Int!, $cursor: String) {
    materialpassportIndex(first: $count, after: $cursor) {
      ...Materialpassports_materialpassportIndex
    }
  }
`;

function Materialpassports() {
  const [first, setFirst] = useState(10); // number of items to fetch per page
  const [after, setAfter] = useState(null); // cursor for pagination

  const { materialpassportIndex } = useLazyLoadQuery(MaterialpassportsQuery, { first, after });

  const handleLoadMore = () => {
    const { endCursor } = materialpassportIndex.pageInfo;
    setAfter(endCursor);
    setFirst(first + 10); // increase the number of items to fetch by 10
  };

  return (
    <>
      <ul>
        {materialpassportIndex.edges.map(({ node }) => (
          <li key={node.id}>
            <h2>{node.name}</h2>
            <p>Completed: {node.completed ? 'Yes' : 'No'}</p>
          </li>
        ))}
      </ul>
      {materialpassportIndex.pageInfo.hasNextPage && (
        <button onClick={handleLoadMore}>Load More</button>
      )}
    </>
  );
}

export default Materialpassports;
dabuchera commented 1 year ago

Solution here.

https://relay.dev/docs/api-reference/use-refetchable-fragment/

The @refetchable directive can only be added to fragments that are "refetchable", that is, on fragments that are declared on Viewer or Query types, or on a type that implements Node (i.e. a type that has an id).

Therefore composedb has to support this directive.

pradel commented 1 year ago

Didn't manage to make it work neither

dabuchera commented 1 year ago

Thanks for trying. Let's see if it works when more directives are supported.

dabuchera commented 1 year ago

https://github.com/RevereCRE/relay-nextjs