Skip to content

Commit 65cb143

Browse files
committed
09-GraphQL Pagination with Apollo Client in React
1 parent 2fd3f5b commit 65cb143

File tree

4 files changed

+112
-12
lines changed

4 files changed

+112
-12
lines changed

src/Button/index.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,21 @@ const Button = ({
1818
</button>
1919
);
2020

21+
const ButtonUnobtrusive = ({
22+
children,
23+
className,
24+
type = 'button',
25+
...props
26+
}) => (
27+
<button
28+
className={`${className} Button_unobtrusive`}
29+
type={type}
30+
{...props}
31+
>
32+
{children}
33+
</button>
34+
);
35+
36+
export { ButtonUnobtrusive };
37+
2138
export default Button;

src/FetchMore/index.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import React from 'react';
2+
3+
import Loading from '../Loading';
4+
import { ButtonUnobtrusive } from '../Button';
5+
6+
import './style.css';
7+
8+
const FetchMore = ({
9+
loading,
10+
hasNextPage,
11+
variables,
12+
updateQuery,
13+
fetchMore,
14+
children,
15+
}) => (
16+
<div className="FetchMore">
17+
{loading ? (
18+
<Loading />
19+
) : (
20+
hasNextPage && (
21+
<ButtonUnobtrusive
22+
className="FetchMore-button"
23+
onClick={() => fetchMore({ variables, updateQuery })}
24+
>
25+
More {children}
26+
</ButtonUnobtrusive>
27+
)
28+
)}
29+
</div>
30+
);
31+
32+
export default FetchMore;

src/Profile/index.js

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,22 @@ import Loading from '../Loading';
77
import ErrorMessage from '../Error';
88

99
const GET_REPOSITORIES_OF_CURRENT_USER = gql`
10-
{
10+
query($cursor: String) {
1111
viewer {
1212
repositories(
1313
first: 5
1414
orderBy: { direction: DESC, field: STARGAZERS }
15+
after: $cursor
1516
) {
1617
edges {
1718
node {
1819
...repository
1920
}
2021
}
22+
pageInfo {
23+
endCursor
24+
hasNextPage
25+
}
2126
}
2227
}
2328
}
@@ -26,19 +31,28 @@ const GET_REPOSITORIES_OF_CURRENT_USER = gql`
2631
`;
2732

2833
const Profile = () => (
29-
<Query query={GET_REPOSITORIES_OF_CURRENT_USER}>
30-
{({ data, loading, error }) => {
34+
<Query
35+
query={GET_REPOSITORIES_OF_CURRENT_USER}
36+
notifyOnNetworkStatusChange={true}
37+
>
38+
{({ data, loading, error, fetchMore }) => {
3139
if (error) {
3240
return <ErrorMessage error={error} />;
3341
}
3442

3543
const { viewer } = data;
3644

37-
if (loading || !viewer) {
45+
if (loading && !viewer) {
3846
return <Loading />;
3947
}
4048

41-
return <RepositoryList repositories={viewer.repositories} />;
49+
return (
50+
<RepositoryList
51+
loading={loading}
52+
repositories={viewer.repositories}
53+
fetchMore={fetchMore}
54+
/>
55+
);
4256
}}
4357
</Query>
4458
);
Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,51 @@
1-
import React from 'react';
1+
import React, { Fragment } from 'react';
22

3+
import FetchMore from '../../FetchMore';
34
import RepositoryItem from '../RepositoryItem';
45

56
import '../style.css';
67

7-
const RepositoryList = ({ repositories }) =>
8-
repositories.edges.map(({ node }) => (
9-
<div key={node.id} className="RepositoryItem">
10-
<RepositoryItem {...node} />
11-
</div>
12-
));
8+
const updateQuery = (previousResult, { fetchMoreResult }) => {
9+
if (!fetchMoreResult) {
10+
return previousResult;
11+
}
12+
13+
return {
14+
...previousResult,
15+
viewer: {
16+
...previousResult.viewer,
17+
repositories: {
18+
...previousResult.viewer.repositories,
19+
...fetchMoreResult.viewer.repositories,
20+
edges: [
21+
...previousResult.viewer.repositories.edges,
22+
...fetchMoreResult.viewer.repositories.edges,
23+
],
24+
},
25+
},
26+
};
27+
};
28+
29+
const RepositoryList = ({ repositories, loading, fetchMore }) => (
30+
<Fragment>
31+
{repositories.edges.map(({ node }) => (
32+
<div key={node.id} className="RepositoryItem">
33+
<RepositoryItem {...node} />
34+
</div>
35+
))}
36+
37+
<FetchMore
38+
loading={loading}
39+
hasNextPage={repositories.pageInfo.hasNextPage}
40+
variables={{
41+
cursor: repositories.pageInfo.endCursor,
42+
}}
43+
updateQuery={updateQuery}
44+
fetchMore={fetchMore}
45+
>
46+
Repositories
47+
</FetchMore>
48+
</Fragment>
49+
);
1350

1451
export default RepositoryList;

0 commit comments

Comments
 (0)