You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/content/8/en/part8b.md
+10-44Lines changed: 10 additions & 44 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -7,7 +7,7 @@ lang: en
7
7
8
8
<divclass="content">
9
9
10
-
We will next implement a React app which uses the GraphQL server we created.
10
+
We will next implement a React app that uses the GraphQL server we created.
11
11
12
12
The current code of the server can be found on [GitHub](https://github.com/fullstack-hy2020/graphql-phonebook-backend/tree/part8-3), branch <i>part8-3</i>.
13
13
@@ -23,7 +23,7 @@ At the moment, there are two good options: [Relay](https://facebook.github.io/re
23
23
24
24
### Apollo client
25
25
26
-
Let us create a new React-app, and can continue installing dependencies required by [Apollo client](https://www.apollographql.com/docs/react/get-started/).
26
+
Let us create a new Reactapp, and can continue installing dependencies required by [Apollo client](https://www.apollographql.com/docs/react/get-started/).
27
27
28
28
```bash
29
29
npm install @apollo/client graphql
@@ -152,7 +152,7 @@ if (result.loading) {
152
152
}
153
153
```
154
154
155
-
When a response is received, the result of the <i>allPersons</i> query can be found from the <i>data</i> field, and we can render the list of names to the screen.
155
+
When a response is received, the result of the <i>allPersons</i> query can be found in the data</i> field, and we can render the list of names to the screen.
156
156
157
157
```js
158
158
<div>
@@ -331,7 +331,7 @@ const result = useQuery(FIND_PERSON, {
331
331
})
332
332
```
333
333
334
-
When user is not interested in seeing the detailed info of any person, the state variable <i>nameToSearch</i> is null and the query is not executed.
334
+
When the user is not interested in seeing the detailed info of any person, the state variable <i>nameToSearch</i> is null and the query is not executed.
335
335
336
336
If the state <i>nameToSearch</i> has a value and the query result is ready, the component <i>Person</i> renders the detailed info of a person:
337
337
@@ -346,11 +346,11 @@ if (nameToSearch && result.data) {
When a user wants to return to the persons list, the *nameToSearch* state is set to *null*.
353
+
When a user wants to return to the person list, the *nameToSearch* state is set to *null*.
354
354
355
355
The current code of the application can be found on [GitHub](https://github.com/fullstack-hy2020/graphql-phonebook-frontend/tree/part8-1) branch <i>part8-1</i>.
356
356
@@ -461,7 +461,6 @@ const PersonForm = () => {
461
461
exportdefaultPersonForm
462
462
```
463
463
464
-
<!-- Lomakkeen koodi on suoraviivainen, mielenkiintoiset rivit on korostettu. Mutaation suorittava funktio saadaan luotua _useMutation_-hookin avulla. Hook palauttaa kyselyfunktion <i>taulukon</i> ensimmäisenä alkiona: -->
465
464
The code of the form is straightforward and the interesting lines have been highlighted.
466
465
We can define mutation functions using the *useMutation* hook.
467
466
The hook returns an <i>array</i>, the first element of which contains the function to cause the mutation.
@@ -470,7 +469,6 @@ The hook returns an <i>array</i>, the first element of which contains the functi
The pros and cons of this solution are almost opposite of the previous one's. There is no extra web traffic, because queries are not done just in case. However, if one user now updates the state of the server, the changes do not show to other users immediately.
533
+
The pros and cons of this solution are almost opposite of the previous one. There is no extra web traffic because queries are not done just in case. However, if one user now updates the state of the server, the changes do not show to other users immediately.
536
534
537
535
If you want to do multiple queries, you can pass multiple objects inside refetchQueries. This will allow you to update different parts of your app at the same time. Here is an example:
538
536
@@ -589,7 +587,7 @@ Trying to create a person with invalid data causes an error:
589
587
590
588
We should handle the exception. We can register an error handler function to the mutation using the *useMutation* hook's *onError* [option](https://www.apollographql.com/docs/react/api/react/hooks/#params-2).
591
589
592
-
Let's register the mutation with an error handler which uses the *setError*
590
+
Let's register the mutation with an error handler that uses the _setError_*
593
591
function it receives as a parameter to set an error message:
We have to dig quite deep to the error object until we find the proper error messages...
614
-
615
611
We can then render the error message on the screen as necessary:
616
612
617
613
```js
@@ -784,36 +780,6 @@ If a person cannot be found, or the *result.data.editNumber* is *null*, the comp
784
780
We want to set the error message only when the result of the mutation
785
781
*result.data* changes, so we use the useEffect hook to control setting the error message.
786
782
787
-
Using useEffect causes an ESLint warning:
788
-
789
-

790
-
791
-
The warning is pointless, and the easiest solution is to ignore the ESLint rule on the line:
792
-
793
-
```js
794
-
useEffect(() => {
795
-
if (result.data&&!result.data.editNumber) {
796
-
setError('name not found')
797
-
}
798
-
// highlight-start
799
-
}, [result.data]) // eslint-disable-line
800
-
// highlight-end
801
-
```
802
-
803
-
We could try to get rid of the warning by adding the *setError* function to useEffect's second parameter array:
804
-
805
-
```js
806
-
useEffect(() => {
807
-
if (result.data&&!result.data.editNumber) {
808
-
setError('name not found')
809
-
}
810
-
// highlight-start
811
-
}, [result.data, setError])
812
-
// highlight-end
813
-
```
814
-
815
-
However, this solution does not work if the *notify* function is not wrapped to a [useCallback](https://react.dev/reference/react/useCallback) function. If it's not, this results in an endless loop. When the *App* component is rerendered after a notification is removed, a <i>new version</i> of *notify* gets created which causes the effect function to be executed, which causes a new notification, and so on, and so on...
816
-
817
783
The current code of the application can be found on [GitHub](https://github.com/fullstack-hy2020/graphql-phonebook-frontend/tree/part8-4) branch <i>part8-4</i>.
Current application code can be found on [Github](https://github.com/fullstack-hy2020/graphql-phonebook-frontend/tree/part8-6), branch <i>part8-6</i>.
222
-
223
221
### Updating cache, revisited
224
222
225
223
We have to [update](/en/part8/react_and_graph_ql#updating-the-cache) the cache of the Apollo client on creating new persons. We can update it using the mutation's *refetchQueries* option to define that the
The callback function is given a reference to the cache and the data returned by the mutation as parameters. For example, in our case, this would be the created person.
270
268
271
269
Using the function [updateQuery](https://www.apollographql.com/docs/react/caching/cache-interaction/#using-updatequery-and-updatefragment) the code updates the
272
-
query <em>ALL\_PERSONS</em> in cache by adding the new person to the cached data.
270
+
query ALLPERSONS in the cache by adding the new person to the cached data.
273
271
274
272
In some situations, the only sensible way to keep the cache up to date is using the *update* callback.
275
273
276
274
When necessary, it is possible to disable cache for the whole application or [single queries](https://www.apollographql.com/docs/react/api/react/hooks/#options) by setting the field managing the use of cache, [fetchPolicy](https://www.apollographql.com/docs/react/data/queries/#configuring-fetch-logic) as <em>no-cache</em>.
277
275
278
-
Be diligent with the cache. Old data in cache can cause hard-to-find bugs. As we know, keeping the cache up to date is very challenging. According to a coder proverb:
276
+
Be diligent with the cache. Old data in the cache can cause hard-to-find bugs. As we know, keeping the cache up to date is very challenging. According to a coder proverb:
279
277
280
278
> <i>There are only two hard things in Computer Science: cache invalidation and naming things.</i> Read more [here](https://martinfowler.com/bliki/TwoHardThings.html).
281
279
282
-
The current code of the application can be found on [Github](https://github.com/fullstack-hy2020/graphql-phonebook-frontend/tree/part8-7), branch <i>part8-7</i>.
280
+
The current code of the application can be found on [Github](https://github.com/fullstack-hy2020/graphql-phonebook-frontend/tree/part8-5), branch <i>part8-5</i>.
Copy file name to clipboardExpand all lines: src/content/8/en/part8e.md
+4-4Lines changed: 4 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -629,9 +629,9 @@ It's possible to test the subscriptions with the Apollo Explorer like this:
629
629
630
630

631
631
632
-
When the blue button <i>PersonAdded</i> is pressed, Explorer starts to wait for a new person to be added. On addition (that you need to do from another browser window), the info of the added person appears in the right side of the Explorer.
632
+
When the blue button <i>PersonAdded</i> is pressed, Explorer starts to wait for a new person to be added. On addition (that you need to do from another browser window), the info of the added person appears on the right side of the Explorer.
633
633
634
-
If the subscription does not work, check that you have correct connection settings:
634
+
If the subscription does not work, check that you have the correct connection settings:
635
635
636
636

637
637
@@ -642,7 +642,7 @@ Implementing subscriptions involves a lot of configurations. You will be able to
642
642
### Subscriptions on the client
643
643
644
644
In order to use subscriptions in our React application, we have to do some changes, especially to its [configuration](https://www.apollographql.com/docs/react/data/subscriptions/).
645
-
The configuration in <i>index.js</i> has to be modified like so:
645
+
The configuration in <i>main.jsx</i> has to be modified like so:
The final code of the client can be found on [GitHub](https://github.com/fullstack-hy2020/graphql-phonebook-frontend/tree/part8-9), branch <i>part8-9</i>.
855
+
The final code of the client can be found on [GitHub](https://github.com/fullstack-hy2020/graphql-phonebook-frontend/tree/part8-6), branch <i>part8-6</i>.
Copy file name to clipboardExpand all lines: src/content/8/fi/osa8.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -10,7 +10,7 @@ Kurssin uudessa osassa käsitellään GraphQL:ää, eli Facebookin kehittämää
10
10
11
11
Katso <atarget="_BLANK"href='https://www.youtube.com/watch?v=R7bXa7g6YuQ&list=PLumQiZ25uijis31zaRL7rhzLalSwLqUtm&index=4&t=0s'>täältä</a> Houston Inc:n Niko Salmisen GraphQL:ää käsittelevä vierailuluento.
12
12
13
-
<i>Osa päivitetty 5.2.2023</i>
14
-
- <i>Backend muutettu käyttämään Apollo Server -kirjaston versiota 4.0</i>
Jos henkilöä ei löytynyt, eli kyselyn tulos _result.data.editNumber_ on _null_, asettaa komponentti propseina saamansa callback-funktion avulla sopivan virheilmoituksen. Virheilmoituksen asettamista kontrolloidaan useEffect-hookin avulla, eli virheviesti halutaan asettaa ainoastaan jos mutaation tulos _result.data_ muuttuu.
758
755
759
-
useEffect aiheuttaa ESLint-virheilmoituksen:
760
-
761
-

762
-
763
-
Varoitus on aiheeton, ja pääsemme helpoimmalla ignoroimalla ESLint-säännön riviltä:
764
-
765
-
```js
766
-
useEffect(() => {
767
-
if ( result.data&&!result.data.editNumber) {
768
-
setError('name not found')
769
-
}
770
-
// highlight-start
771
-
}, [result.data]) // eslint-disable-line
772
-
// highlight-end
773
-
```
774
-
775
-
Voisimme yrittää päästä varoituksesta eroon lisäämällä funktion _setError_ useEffectin toisena parametrina olevaan taulukkoon:
776
-
777
-
```js
778
-
useEffect(() => {
779
-
if ( result.data&&!result.data.editNumber) {
780
-
setError('name not found')
781
-
}
782
-
// highlight-start
783
-
}, [result.data, setError])
784
-
// highlight-end
785
-
```
786
-
787
-
Tämä ratkaisu ei kuitenkaan toimi, ellei _setError_-funktiota ole määritelty [useCallback](https://reactjs.org/docs/hooks-reference.html#usecallback)-funktioon käärittynä. Jos näin ei tehdä, seurauksena on ikuinen luuppi, sillä aina kun komponentti _App_ renderöidään uudelleen notifikaation poistamisen jälkeen, syntyy <i>uusi versio</i> funktiosta _setError_ ja se taas aiheuttaa efektifunktion uudelleensuorituksen ja taas uuden notifikaation...
788
-
789
756
Sovelluksen tämänhetkinen koodi on [GitHubissa](https://github.com/fullstack-hy2020/graphql-phonebook-frontend/tree/part8-4), branchissa <i>part8-4</i>.
@@ -280,7 +278,7 @@ Välimuistin kanssa kannattaa olla tarkkana. Välimuistissa oleva epäajantasain
280
278
> <i>There are only two hard things in Computer Science: cache invalidation and naming things.</i> Katso lisää [täältä](https://www.google.com/search?q=two+hard+things+in+Computer+Science&oq=two+hard+things+in+Computer+Science).
281
279
282
280
283
-
Sovelluksen tämän vaiheen koodi [GitHubissa](https://github.com/fullstack-hy2020/graphql-phonebook-frontend/tree/part8-7), branchissa <i>part8-7</i>.
281
+
Sovelluksen tämän vaiheen koodi [GitHubissa](https://github.com/fullstack-hy2020/graphql-phonebook-frontend/tree/part8-5), branchissa <i>part8-5</i>.
0 commit comments