Skip to content

Instantly share code, notes, and snippets.

@zth
Created September 16, 2018 19:33
Show Gist options
  • Save zth/1919a797a98bff4fb9810aac45a5ba53 to your computer and use it in GitHub Desktop.
Save zth/1919a797a98bff4fb9810aac45a5ba53 to your computer and use it in GitHub Desktop.
A typical pagination view.
// @flow
import { graphql, createPaginationContainer } from 'react-relay';
import type { UserPetsList_user } from './__generated__/UserPetsList_user.graphql';
import * as React from 'react';
import SinglePet from './SinglePet';
type Props = {|
relay: {
hasMore: () => boolean,
loadMore(pageSize: number, callback: ?(error: ?Error) => void): ?Object,
isLoading: () => boolean
},
user: UserPetsList_user
|};
type State = {|
loading: boolean
|};
/**
* This is the pagination container showing the list of pets.
* It also shows a "Load more" button, which loads more pets until
* there are no more to load.
*/
class UserPetsList extends React.Component<Props, State> {
state = {
loading: false
};
loadMore = () => {
const { relay } = this.props;
if (relay.hasMore() && !relay.isLoading()) {
this.setState({
loading: true
});
relay.loadMore(2, () => {
this.setState({
loading: false
});
});
}
};
render() {
const { user, relay } = this.props;
const { loading } = this.state;
// TIP: Type safe way of extracting connection nodes to an array with Flow.
const userPets =
user.pets && user.pets.edges
? user.pets.edges
.filter(Boolean) // Remove any null edges
.map(edge => edge.node) // Extract node
.filter(Boolean) // Remove any null nodes
: [];
// Flow now understands this is a list of nodes with the same shape as we request from the GraphQL API.
// flow type-at-pos gives: [] | Array<{|+id: string, +name: string|}>
return (
<div>
<h1>Pets of {user.name}</h1>
<div>
{userPets.map(pet => (
<div key={pet.id} data-testid="Pet">
<SinglePet pet={pet} />
</div>
))}
{relay.hasMore() && (
<button onClick={this.loadMore} disabled={loading}>
See more pets
</button>
)}
{loading && <div>Loading more pets...</div>}
</div>
</div>
);
}
}
export default createPaginationContainer(
UserPetsList,
graphql`
fragment UserPetsList_user on User {
id
name
pets(first: $count, after: $cursor)
@connection(key: "UserPetsList_pets") {
edges {
node {
id
...SinglePet_pet
}
}
}
}
`,
{
getVariables(props: Props, { count, cursor }) {
return {
userId: props.user.id,
count,
cursor
};
},
query: graphql`
query UserPetsListPaginationQuery(
$count: Int!
$cursor: String
$userId: ID!
) {
User(userId: $userId) {
...UserPetsList_user
}
}
`
}
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment