Skip to content

Instantly share code, notes, and snippets.

@lprhodes
Created September 1, 2022 07:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lprhodes/bad7e63d101dcf689fce5f037073165e to your computer and use it in GitHub Desktop.
Save lprhodes/bad7e63d101dcf689fce5f037073165e to your computer and use it in GitHub Desktop.
Relay Pagination Mock
// React Component
function ProfileBookmarksScreen(props): JSX.Element {
const { componentId, relayPagination } = props
const { data: user, loadNext, hasNext, refetch } = relayPagination
return (
<>
<div>
{(user?.bookmarkedPostsWithCursor?.edges ?? []).map((edge) => {
const node = edge?.node
return (
<Suspense fallback={<LoadingSpinner />}>
<DiscussCell
key={`bookmark-posts-${node?.id}`}
componentId={componentId}
post={node}
user={user}
/>
</Suspense>
)
})}
</div>
{hasNext && (
<Button
title="Load More"
onPress={() => {
loadNext(10)
}}
/>
)}
<Button
title="Refetch"
onPress={() => {
refetch({}, { fetchPolicy: 'store-and-network' })
}}
/>
</>
)
const ProfileBookmarksGraphQL = graphql`
query BookmarksQuery($userID: ID!, $first: Int, $after: String) {
user(id: $userID) {
...Bookmarks_query
}
}
`
const ProfileBookmarksRefetchGraphQL = graphql`
fragment Bookmarks_query on User @refetchable(queryName: "BookmarksPaginationQuery") {
name
bookmarkedPostsWithCursor(first: $first, after: $after)
@connection(key: "Bookmarks_User_bookmarkedPostsWithCursor") {
edges {
node {
id
creationTimestamp
...Cell_FeedPostCell_Post
}
}
pageInfo {
hasNextPage
endCursor
}
}
...Cell_FeedPostCell_User
}
`
export default withPaginationGraphQL({
WrappedComponent: ProfileBookmarksScreen,
graphQLQuery: ProfileBookmarksGraphQL,
refetchableQueryFragment: ProfileBookmarksRefetchGraphQL,
variables: (props) => {
return { userID: props.userID, after: null, first: null }
}
})
export function useGraphQLLoader(
query,
variables,
options
): PreloadedQuery {
// GraphQL
const [queryRef, loadQuery] = useQueryLoader(query)
useEffect(() => {
loadQuery(variables, { fetchPolicy: 'store-and-network', ...options })
}, [])
return queryRef
}
import React from 'react'
import {
usePaginationFragment,
usePreloadedQuery
} from 'react-relay'
import { useGraphQLLoader } from './useGraphQLLoader'
export function withPaginationGraphQL(props) {
const { graphQLQuery, variables, queryOptions } = props
return function Parent(parentProps) {
// GraphQL Parent
const queryRef = useGraphQLLoader(graphQLQuery, variables(parentProps), queryOptions)
if (!queryRef) return null
return <PreloadChild {...props} queryRef={queryRef} componentId={parentProps.componentId} />
}
}
function PreloadChild(props): JSX.Element {
const { graphQLQuery, queryRef } = props
// GraphQL Child
const data = usePreloadedQuery(graphQLQuery, queryRef)
return <RefetchableChild {...props} queryData={data} />
}
function RefetchableChild(props): JSX.Element {
const { WrappedComponent, refetchableQueryFragment, queryData } = props
const relayPagination = usePaginationFragment(refetchableQueryFragment, queryData.user)
return <WrappedComponent {...props} relayPagination={relayPagination} />
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment