The @PaginationFragment
property wrapper is very similar to a @Fragment, but it supports loading additional items upon request. When using a pagination fragment, you don't have to load an entire list of data all at once. You can control when you load more, and you'll be able to easily update your UI accordingly.
A @PaginationFragment
expects your schema to be structured in a specific way to support paging. See the GraphQL Cursor Connections Specification for more details.
import SwiftUI
import RelaySwiftUI
private let userFragment = graphql("""
fragment ToDoList_user on User
@refetchable(queryName: "ToDoListPaginationQuery")
@argumentDefinitions(
count: { type: "Int", defaultValue: 10 }
cursor: { type: "Cursor" }
) {
todos(first: $count, after: $cursor)
@connection(key: "ToDoList_todos") {
edges {
node {
id
...ToDoItem_todo
}
}
}
}
""")
struct ToDoList: View {
@PaginationFragment<ToDoList_user> var user
var body: some View {
if let user = user {
List {
ForEach(user.todos ?? []) { todo in
ToDoItem(todo: todo)
}
if user.isLoadingNext {
Text("Loading…").foregroundColor(.secondary)
} else if user.hasNext {
Button("Load more tweets…") {
user.loadNext(10)
}
}
}
}
}
}
There are a few special requirements for the fragment in order for it to be valid to use with a @PaginationFragment
:
@refetchable
directive that names a query operation that will be generated to fetch additional data for the fragment. Using @refetchable
requires that the fragment be declared on Query
, Viewer
, or a type that implements the Node
. Otherwise, Relay won't know where in the graph to fetch the new data from.@connection
directive that marks the connection field to use for paging. See the GraphQL Cursor Connections Specification for more about connections.F
: A type parameter (surrounded in <>
) for the type of the fragment to use. The type will be generated by the Relay compiler with a name matching the fragment name in the GraphQL snippet.The @PaginationFragment
property will be a read-only optional value with the fields the fragment requests. This value will automatically update and re-render the view when more items are loaded or when the Relay store updates any relevant records.
The value will also include some additional properties related to paging:
isLoadingNext: Bool
: Indicates if there is an in-flight request to load more items from the end of the list.isLoadingPrevious: Bool
: Indicates if there is an in-flight request to load more items from the beginning of the list.hasNext: Bool
: Indicates if there are more items that can be fetched from the end of the list.hasPrevious: Bool
: Indicates if there are more items that can be fetched from the beginning of the list.loadNext(_ count: Int)
: Function that can be called to fetch the next count
items from the end of the list.loadPrevious(_ count: Int)
: Function that can be called to fetch the previous count
items from the beginning of the list.@connection
fields as Collections