Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Comparison of pagination without and without Relay Hooks
/**
* This file shows an example of pagination using the new Relay Hooks
* APIs. Please see old_container_based_api.react.jsx for an example of
* how this might have looked using the previous, Container-based APIs.
*/
'use strict';
import type {UserComponent_user$key} from 'UserComponent_user.graphql';
import {graphql, usePaginationFragment} from 'CometRelay';
import * as React from 'React';
import {useCallback} from 'React';
type Props = {
user: UserComponent_user$key,
};
graphql`
query UserComponentQuery($after: ID, $count: Int!) {
viewer {
actor {
... on User {
...UserComponent_user
}
}
}
}
`;
function FriendsList() {}
function Button() {}
function InlineSpinner() {}
function UserComponent(props: Props) {
const {data, loadNext, hasNext, isLoadingNext} = usePaginationFragment(
graphql`
fragment UserComponent_user on User
@refetchable(queryName: "UserComponentRefetchQuery") {
friends(first: $count, after: $after)
@connection(key: "UserComponent_user_friends") {
edges {
node {
name
}
}
}
}
`,
props.user,
);
return (
<>
<FriendsList friends={data?.friends?.edges} />
<Button onClick={() => loadNext(5)} disabled={!hasNext || isLoadingNext}>
Load More
{isLoadingNext && <InlineSpinner />}
</Button>
</>
);
}
/**
* This file shows an example of pagination using the pre-Hooks,
* Container-based APIs. Please see new_hooks_api.react.jsx for an
* example of how this example can be simplified by switching
* to the new Relay Hooks APIs.
*/
'use strict';
import type {$RelayProps} from 'RelayModern';
import type {RelayPaginationProp} from 'RelayModern';
import type {UserContainerComponent_user} from 'UserContainerComponent_user.graphql';
import * as React from 'React';
import {createPaginationContainer, graphql} from 'RelayModern';
type Props = {
relay: RelayPaginationProp,
user: UserContainerComponent_user,
};
type State = {
loading: boolean,
};
function FriendsList() {}
function Button() {}
function InlineSpinner() {}
class UserContainerComponent extends React.Component<Props, State> {
render(): React.Node {
const isLoading = this.props.relay.isLoading() || this.state.loading;
const hasMore = this.props.relay.hasMore();
return (
<>
<FriendsList friends={this.props.user?.friends} />
<Button
onClick={() => this.loadMore()}
disabled={!hasMore || isLoading}>
Load More
{isLoading && <InlineSpinner />}
</Button>
</>
);
}
loadMore() {
if (
!this.props.relay.hasMore() ||
this.props.relay.isLoading() ||
this.state.loading
) {
return;
}
this.setState({loading: true});
this.props.relay.loadMore(5, () => this.setState({loading: false}));
}
}
export default (createPaginationContainer(
UserContainerComponent,
{
user: graphql`
fragment UserContainerComponent_user on User
@argumentDefinitions(count: {type: "Int!"}, cursor: {type: "ID"})
@refetchable(queryName: "UserComponentRefetchQuery") {
friends(first: $count, after: $cursor)
@connection(key: "UserComponent_user_friends") {
edges {
node {
name
}
}
}
}
`,
},
{
direction: 'forward',
getConnectionFromProps(props: Props) {
return props.user?.friends;
},
getFragmentVariables(vars, count) {
return {...vars, count};
},
getVariables(props: Props, {count, cursor}) {
return {
cursor,
count,
};
},
query: graphql`
query UserContainerComponentQuery {
viewer {
actor {
... on User {
...UserContainerComponent_user @arguments(count: 10)
}
}
}
}
`,
},
): React.ComponentType<
$RelayProps<
React.ElementConfig<typeof UserContainerComponent>,
RelayPaginationProp,
>,
>);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment