Skip to content

Commit 24bb647

Browse files
committed
07-Local State Management with Apollo Client in React
1 parent 694cc4e commit 24bb647

File tree

4 files changed

+147
-36
lines changed

4 files changed

+147
-36
lines changed

src/Profile/index.js

Lines changed: 20 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import React from 'react';
22
import gql from 'graphql-tag';
3-
import { graphql } from 'react-apollo';
3+
import { Query } from 'react-apollo';
44

5-
import RepositoryList from '../Repository';
5+
import RepositoryList, { REPOSITORY_FRAGMENT } from '../Repository';
66
import Loading from '../Loading';
77
import ErrorMessage from '../Error';
88

@@ -15,44 +15,32 @@ const GET_REPOSITORIES_OF_CURRENT_USER = gql`
1515
) {
1616
edges {
1717
node {
18-
id
19-
name
20-
url
21-
descriptionHTML
22-
primaryLanguage {
23-
name
24-
}
25-
owner {
26-
login
27-
url
28-
}
29-
stargazers {
30-
totalCount
31-
}
32-
viewerHasStarred
33-
watchers {
34-
totalCount
35-
}
36-
viewerSubscription
18+
...repository
3719
}
3820
}
3921
}
4022
}
4123
}
24+
25+
${REPOSITORY_FRAGMENT}
4226
`;
4327

44-
const Profile = ({ data, loading, error }) => {
45-
if (error) {
46-
return <ErrorMessage error={error} />;
47-
}
28+
const Profile = () => (
29+
<Query query={GET_REPOSITORIES_OF_CURRENT_USER}>
30+
{({ data, loading, error }) => {
31+
if (error) {
32+
return <ErrorMessage error={error} />;
33+
}
4834

49-
const { viewer } = data;
35+
const { viewer } = data;
5036

51-
if (loading || !viewer) {
52-
return <Loading />;
53-
}
37+
if (loading || !viewer) {
38+
return <Loading />;
39+
}
5440

55-
return <RepositoryList repositories={viewer.repositories} />;
56-
};
41+
return <RepositoryList repositories={viewer.repositories} />;
42+
}}
43+
</Query>
44+
);
5745

58-
export default graphql(GET_REPOSITORIES_OF_CURRENT_USER)(Profile);
46+
export default Profile;

src/Repository/RepositoryItem/index.js

Lines changed: 97 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React from 'react';
22
import { Mutation } from 'react-apollo';
33

4+
import REPOSITORY_FRAGMENT from '../fragments';
45
import Link from '../../Link';
56
import Button from '../../Button';
67

@@ -20,6 +21,91 @@ const VIEWER_SUBSCRIPTIONS = {
2021
const isWatch = viewerSubscription =>
2122
viewerSubscription === VIEWER_SUBSCRIPTIONS.SUBSCRIBED;
2223

24+
const updateWatch = (
25+
client,
26+
{
27+
data: {
28+
updateSubscription: {
29+
subscribable: { id, viewerSubscription },
30+
},
31+
},
32+
},
33+
) => {
34+
const repository = client.readFragment({
35+
id: `Repository:${id}`,
36+
fragment: REPOSITORY_FRAGMENT,
37+
});
38+
39+
let { totalCount } = repository.watchers;
40+
totalCount =
41+
viewerSubscription === VIEWER_SUBSCRIPTIONS.SUBSCRIBED
42+
? totalCount + 1
43+
: totalCount - 1;
44+
45+
client.writeFragment({
46+
id: `Repository:${id}`,
47+
fragment: REPOSITORY_FRAGMENT,
48+
data: {
49+
...repository,
50+
watchers: {
51+
...repository.watchers,
52+
totalCount,
53+
},
54+
},
55+
});
56+
};
57+
58+
const updateAddStar = (
59+
client,
60+
{
61+
data: {
62+
addStar: {
63+
starrable: { id, viewerHasStarred },
64+
},
65+
},
66+
},
67+
) =>
68+
client.writeFragment({
69+
id: `Repository:${id}`,
70+
fragment: REPOSITORY_FRAGMENT,
71+
data: getUpdatedStarData(client, id, viewerHasStarred),
72+
});
73+
74+
const updateRemoveStar = (
75+
client,
76+
{
77+
data: {
78+
removeStar: {
79+
starrable: { id, viewerHasStarred },
80+
},
81+
},
82+
},
83+
) => {
84+
client.writeFragment({
85+
id: `Repository:${id}`,
86+
fragment: REPOSITORY_FRAGMENT,
87+
data: getUpdatedStarData(client, id, viewerHasStarred),
88+
});
89+
};
90+
91+
const getUpdatedStarData = (client, id, viewerHasStarred) => {
92+
const repository = client.readFragment({
93+
id: `Repository:${id}`,
94+
fragment: REPOSITORY_FRAGMENT,
95+
});
96+
97+
let { totalCount } = repository.stargazers;
98+
totalCount = viewerHasStarred ? totalCount + 1 : totalCount - 1;
99+
100+
return {
101+
...repository,
102+
stargazers: {
103+
...repository.stargazers,
104+
totalCount,
105+
},
106+
};
107+
};
108+
23109
const RepositoryItem = ({
24110
id,
25111
name,
@@ -47,6 +133,7 @@ const RepositoryItem = ({
47133
? VIEWER_SUBSCRIPTIONS.UNSUBSCRIBED
48134
: VIEWER_SUBSCRIPTIONS.SUBSCRIBED,
49135
}}
136+
update={updateWatch}
50137
>
51138
{(updateSubscription, { data, loading, error }) => (
52139
<Button
@@ -61,7 +148,11 @@ const RepositoryItem = ({
61148
</Mutation>
62149

63150
{!viewerHasStarred ? (
64-
<Mutation mutation={STAR_REPOSITORY} variables={{ id }}>
151+
<Mutation
152+
mutation={STAR_REPOSITORY}
153+
variables={{ id }}
154+
update={updateAddStar}
155+
>
65156
{(addStar, { data, loading, error }) => (
66157
<Button
67158
className={'RepositoryItem-title-action'}
@@ -72,7 +163,11 @@ const RepositoryItem = ({
72163
)}
73164
</Mutation>
74165
) : (
75-
<Mutation mutation={UNSTAR_REPOSITORY} variables={{ id }}>
166+
<Mutation
167+
mutation={UNSTAR_REPOSITORY}
168+
variables={{ id }}
169+
update={updateRemoveStar}
170+
>
76171
{(removeStar, { data, loading, error }) => (
77172
<Button
78173
className="RepositoryItem-title-action"
@@ -83,8 +178,6 @@ const RepositoryItem = ({
83178
)}
84179
</Mutation>
85180
)}
86-
87-
{/* Here comes your updateSubscription mutation */}
88181
</div>
89182
</div>
90183

src/Repository/fragments.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import gql from 'graphql-tag';
2+
3+
const REPOSITORY_FRAGMENT = gql`
4+
fragment repository on Repository {
5+
id
6+
name
7+
url
8+
descriptionHTML
9+
primaryLanguage {
10+
name
11+
}
12+
owner {
13+
login
14+
url
15+
}
16+
stargazers {
17+
totalCount
18+
}
19+
viewerHasStarred
20+
watchers {
21+
totalCount
22+
}
23+
viewerSubscription
24+
}
25+
`;
26+
27+
export default REPOSITORY_FRAGMENT;

src/Repository/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
import RepositoryList from './RepositoryList';
2+
import REPOSITORY_FRAGMENT from './fragments';
3+
4+
export { REPOSITORY_FRAGMENT };
25

36
export default RepositoryList;

0 commit comments

Comments
 (0)