javascript - Forward and backward pagination with relay js - Stack Overflow

Relay cursor connection specification says:hasNextPage will be false if the client is not paginating wi

Relay cursor connection specification says:

hasNextPage will be false if the client is not paginating with first, or if the client is paginating with first, and the server has determined that the client has reached the end of the set of edges defined by their cursors.

What I understand from that spec is that Relay can only paginate in one direction; forwards or backwards. That seems reasonable for an infinite scroll pagination implementation.

But how would one implement a sequential pages navigation similar to the stackoverflow questions page which can navigate both ways?

Is Relay.js suitable for this kind pagination? I can't rely on hasNextPage and hasPreviousPage field which never has true value unless I paginate with first and last which is also very discouraged.

Relay cursor connection specification says:

hasNextPage will be false if the client is not paginating with first, or if the client is paginating with first, and the server has determined that the client has reached the end of the set of edges defined by their cursors.

What I understand from that spec is that Relay can only paginate in one direction; forwards or backwards. That seems reasonable for an infinite scroll pagination implementation.

But how would one implement a sequential pages navigation similar to the stackoverflow questions page which can navigate both ways?

Is Relay.js suitable for this kind pagination? I can't rely on hasNextPage and hasPreviousPage field which never has true value unless I paginate with first and last which is also very discouraged.

Share Improve this question edited Mar 16, 2017 at 15:09 Chris 59.6k20 gold badges120 silver badges142 bronze badges asked Mar 14, 2017 at 9:50 Mas BagolMas Bagol 4,63711 gold badges48 silver badges78 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 5

What I understand from that spec is that relay can only paginate with single direction, forwards or backwards.

Correct. The original design was exactly that, an infinite scroll pagination. It was never intended to be used for bi-directional pagination.

But how about sequential pages like stackoverflow questions page?

This is quite tricky do to with the default implementation of Relay as it stands today because, as stated above, it was't designed for bi-directional navigation.

That said, you can still achieve this, though not through optimal means.


Method 1 - Passing page info through Relay

This is probably the easiest method to implement, though the less optimal one. It involves passing the page info to Relay as a GraphQL argument. This requires a new Relay query each time you navigate to a new page.

Example

Assume you have a view displaying a list of members. You fetch a list of member nodes with memberList. If you only want to display 10 members per "page" and we're on page 3, you could do:

app: () => Relay.QL`
  fragment on App {
    memberList(page: 3, limit: 10) {
      ...
    }
  }`
}

In your backend your SQL query would now look something like:

SELECT id, username, email FROM members LIMIT 20, 10;

Where 20 is the starting record: (page-1)*10 and 10 is the limit (how many items after the start). So the above will fetch the records 21-30.

Note that you would need initial values for page and limit. So your final query would be:

prepareVariables() {
  return {
    page: 1,
    limit: 10,
  };
},
fragments: {
  app: () => Relay.QL`
    fragment on App {
      memberList(page: $page, limit: $limit) {
        ...
      }
    }`
  }
}

And when navigating to a new page we need to update the values:

_goToPage = (pg) => {
  this.props.relay.setVariables({
    page: pg,
  });
}

Method 2 - Manually managing cursors

This is a slightly hacky implementation in that it essentially gives you a bi-directional navigation, even though is not natively supported. This approach is slightly more optimal to the first one, but sacrifices the ability to jump to a page directly.

Note that we cannot use both first and last:

Including a value for both first and last is strongly discouraged, as it is likely to lead to confusing queries and results.

Hence we would construct our query normally. Something like:

app: () => Relay.QL`
  fragment on App {
    memberList(first: 10, after: $cursor) {
      ...
    }
  }`
}

where the initial value for $cursor is null.

As you navigate to the next page and set the value for $cursor to be the cursor of the last member node, you also save the value in a local stack variable.

This way, whenever you navigate back you would simply pop the last cursor from the stack and use that for your after argument. It requires some extra logic in your application, but this is definitely doable.

Based on Method 2 given by @Chris,

This is my solution in VueJS, it's roughly the same for ReactJS as well.

    loadPage(type) {
      const { endCursor } = this.pageInfo
      let cursor = null 
      if(type === 'previous') {
        this.cursorStack = this.cursorStack.slice(0, this.cursorStack.length - 1)
        cursor = this.cursorStack[this.cursorStack.length - 1]
      }
      else {
        cursor = endCursor
        this.cursorStack = [...this.cursorStack, cursor]
      }
      this.fetchMore({
        variables: { cursor: cursor },
        updateQuery: (previousResult, { fetchMoreResult }) => {
          if (!fetchMoreResult) return previousResult
          return fetchMoreResult
        }
      })
    },

In template:

<button :disabled="!cursorStack.length" @click="loadPage('previous')" />
<button :disabled="!pageInfo.hasNextPage" @click="loadPage('next')" />

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745431206a4627397.html

相关推荐

  • javascript - Forward and backward pagination with relay js - Stack Overflow

    Relay cursor connection specification says:hasNextPage will be false if the client is not paginating wi

    12小时前
    40

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信