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/6/en/part6d.md
+25-29Lines changed: 25 additions & 29 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -50,7 +50,7 @@ The initial code is on GitHub in the repository [https://github.com/fullstack-hy
50
50
51
51
### Managing data on the server with the React Query library
52
52
53
-
We shall now use the [React Query](https://react-query-v3.tanstack.com/) library to store and manage data retrieved from the server.
53
+
We shall now use the [React Query](https://react-query-v3.tanstack.com/) library to store and manage data retrieved from the server.
54
54
55
55
Install the library with the command
56
56
@@ -60,7 +60,6 @@ npm install react-query
60
60
61
61
A few additions to the file <i>index.js</i> are needed to pass the library functions to the entire application:
62
62
63
-
64
63
```js
65
64
importReactfrom'react'
66
65
importReactDOMfrom'react-dom/client'
@@ -109,15 +108,15 @@ const App = () => {
109
108
}
110
109
```
111
110
112
-
Retrieving data from the server is still done in the familiar way with the Axios <i>get</i> method. However, the Axios method call is now wrapped in a [query](https://react-query-v3.tanstack.com/guides/queries) formed with the [useQuery](https://react-query-v3.tanstack.com/reference/useQuery) function. The first parameter of the function call is a string <i>notes</i> which acts as a [key](https://react-query-v3.tanstack.com/guides/query-keys) to the query defined, i.e. the list of notes.
111
+
Retrieving data from the server is still done in the familiar way with the Axios <i>get</i> method. However, the Axios method call is now wrapped in a [query](https://tanstack.com/query/latest/docs/react/guides/queries) formed with the [useQuery](https://tanstack.com/query/latest/docs/react/reference/useQuery) function. The first parameter of the function call is a string <i>notes</i> which acts as a [key](https://tanstack.com/query/latest/docs/react/guides/query-keys) to the query defined, i.e. the list of notes.
113
112
114
-
The return value of the <i>useQuery</i> function is an object that indicates the status of the query. The output to the console illustrates the situation:
113
+
The return value of the <i>useQuery</i> function is an object that indicates the status of the query. The output to the console illustrates the situation:
That is, the first time the component is rendered, the query is still in <i>loading</i> state, i.e. the associated HTTP request is pending. At this stage, only the following is rendered:
119
118
120
-
```
119
+
```html
121
120
<div>loading data...</div>
122
121
```
123
122
@@ -190,7 +189,7 @@ const App = () => {
190
189
}
191
190
```
192
191
193
-
To create a new note, a [mutation](https://react-query-v3.tanstack.com/guides/mutations) is defined using the function [useMutation](https://react-query-v3.tanstack.com/reference/useMutation):
192
+
To create a new note, a [mutation](https://tanstack.com/query/latest/docs/react/guides/mutations) is defined using the function [useMutation](https://tanstack.com/query/latest/docs/react/reference/useMutation):
194
193
195
194
```js
196
195
constnewNoteMutation=useMutation(createNote)
@@ -200,14 +199,13 @@ The parameter is the function we added to the file <i>requests.js</i>, which use
200
199
201
200
The event handler <i>addNote</i> performs the mutation by calling the mutation object's function <i>mutate</i> and passing the new note as a parameter:
Our solution is good. Except it doesn't work. The new note is saved on the server, but it is not updated on the screen.
209
207
210
-
In order to render a new note as well, we need to tell React Query that the old result of the query whose key is the string <i>notes</i> should be [invalidated](https://react-query-v3.tanstack.com/guides/invalidations-from-mutations).
208
+
In order to render a new note as well, we need to tell React Query that the old result of the query whose key is the string <i>notes</i> should be [invalidated](https://tanstack.com/query/latest/docs/react/guides/invalidations-from-mutations).
211
209
212
210
Fortunately, invalidation is easy, it can be done by defining the appropriate <i>onSuccess</i> callback function to the mutation:
213
211
@@ -284,11 +282,11 @@ The application works well, and the code is relatively simple. The ease of makin
284
282
285
283
The consequence of this, of course, is that after the PUT request that causes the note change, the application makes a new GET request to retrieve the query data from the server:
286
284
287
-

285
+

288
286
289
287
If the amount of data retrieved by the application is not large, it doesn't really matter. After all, from a browser-side functionality point of view, making an extra HTTP GET request doesn't really matter, but in some situations it might put a strain on the server.
290
288
291
-
If necessary, it is also possible to optimize performance [by manually updating](https://react-query-v3.tanstack.com/guides/updates-from-mutation-responses) the query state maintained by React Query.
289
+
If necessary, it is also possible to optimize performance [by manually updating](https://tanstack.com/query/latest/docs/react/guides/updates-from-mutation-responses) the query state maintained by React Query.
292
290
293
291
The change for the mutation adding a new note is as follows:
294
292
@@ -317,9 +315,9 @@ It would be relatively easy to make a similar change to a mutation that changes
317
315
318
316
If we closely follow the browser's network tab, we notice that React Query retrieves all notes as soon as we move the cursor to the input field:
319
317
320
-

318
+

321
319
322
-
What is going on? By reading the [documentation](https://react-query-v3.tanstack.com/reference/useQuery), we notice that the default functionality of React Query's queries is that the queries (whose status is <i>stale</i>) are updated when <i>window focus</i>, i.e. the active element of the application's user interface, changes. If we want, we can turn off the functionality by creating a query as follows:
320
+
What is going on? By reading the [documentation](https://tanstack.com/query/latest/docs/react/reference/useQuery), we notice that the default functionality of React Query's queries is that the queries (whose status is <i>stale</i>) are updated when <i>window focus</i>, i.e. the active element of the application's user interface, changes. If we want, we can turn off the functionality by creating a query as follows:
323
321
324
322
```js
325
323
constApp= () => {
@@ -336,14 +334,14 @@ If you put a console.log statement to the code, you can see from browser console
336
334
337
335
The code for the application is in [GitHub](https://github.com/fullstack-hy2020/query-notes/tree/part6-3) in the branch <i>part6-3</i>.
338
336
339
-
React Query is a versatile library that, based on what we have already seen, simplifies the application. Does React Query make more complex state management solutions such as Redux unnecessary? No. React Query can partially replace the state of the application in some cases, but as the [documentation](https://react-query-v3.tanstack.com/guides/does-this-replace-client-state) states
337
+
React Query is a versatile library that, based on what we have already seen, simplifies the application. Does React Query make more complex state management solutions such as Redux unnecessary? No. React Query can partially replace the state of the application in some cases, but as the [documentation](https://tanstack.com/query/latest/docs/react/guides/does-this-replace-client-state) states
340
338
341
339
- React Query is a <i>server-state library</i>, responsible for managing asynchronous operations between your server and client
342
340
- Redux, etc. are <i>client-state libraries</i> that can be used to store asynchronous data, albeit inefficiently when compared to a tool like React Query
343
341
344
342
So React Query is a library that maintains the <i>server state</i> in the frontend, i.e. acts as a cache for what is stored on the server. React Query simplifies the processing of data on the server, and can in some cases eliminate the need for data on the server to be saved in the frontend state.
345
343
346
-
Most React applications need not only a way to temporarily store the served data, but also some solution for how the rest of the frontend state (e.g. the state of forms or notifications) is handled.
344
+
Most React applications need not only a way to temporarily store the served data, but also some solution for how the rest of the frontend state (e.g. the state of forms or notifications) is handled.
347
345
348
346
</div>
349
347
@@ -359,13 +357,12 @@ Implement retrieving anecdotes from the server using React Query.
359
357
360
358
The application should work in such a way that if there are problems communicating with the server, only an error page will be displayed:
361
359
362
-

360
+

363
361
364
-
You can find [here](https://react-query-v3.tanstack.com/guides/queries) info how to detect the possible errors.
362
+
You can find [here](https://tanstack.com/query/latest/docs/react/guides/queries) info how to detect the possible errors.
365
363
366
364
You can simulate a problem with the server by e.g. turning off the JSON Server. Please note that in a problem situation, the query is first in the state <i>isLoading</i> for a while, because if a request fails, React Query tries the request a few times before it states that the request is not successful. You can optionally specify that no retries are made:
367
365
368
-
369
366
```js
370
367
constresult=useQuery(
371
368
'anecdotes', getAnecdotes,
@@ -392,7 +389,7 @@ Implement adding new anecdotes to the server using React Query. The application
392
389
393
390
#### Exercise 6.22
394
391
395
-
Implement voting for anecdotes using again the React Query. The application should automatically render the increased number of votes for the voted anecdote
392
+
Implement voting for anecdotes using again the React Query. The application should automatically render the increased number of votes for the voted anecdote.
396
393
397
394
</div>
398
395
@@ -404,7 +401,7 @@ So even if the application uses React Query, some kind of solution is usually ne
404
401
405
402
Let's look at a simple counter application. The application displays the counter value, and offers three buttons to update the counter status:
406
403
407
-

404
+

408
405
409
406
We shall now implement the counter state management using a Redux-like state management mechanism provided by React's built-in [useReducer](https://beta.reactjs.org/reference/react/useReducer) hook. Code looks like the following:
410
407
@@ -753,7 +750,7 @@ The solution is quite elegant. The entire state of the application, i.e. the val
753
750
754
751
The final code for the application is in [GitHub](https://github.com/fullstack-hy2020/hook-counter/tree/part6-3) in the branch <i>part6-3</i>.
755
752
756
-
As a technical detail, it should be noted that the helper functions <i>useCounterValue</i> and <i>useCounterDispatch</i> are defined as [custom hooks](https://reactjs.org/docs/hooks-custom.html), because calling the hook function <i>useContext</i> is [possible](https://reactjs.org/docs/hooks -rules.html) only from React components or custom hooks. Custom Hooks, on the other hand, are JavaScript functions whose name must start with the string _use_. We will return to custom hooks in a little more detail in [part 7](http://localhost:8000/en/part7/custom_hooks) of the course.
753
+
As a technical detail, it should be noted that the helper functions <i>useCounterValue</i> and <i>useCounterDispatch</i> are defined as [custom hooks](https://reactjs.org/docs/hooks-custom.html), because calling the hook function <i>useContext</i> is [possible](https://reactjs.org/docs/hooks -rules.html) only from React components or custom hooks. Custom hooks are JavaScript functions whose name must start with the string _use_. We will return to custom hooks in a little more detail in [part 7](/en/part7/custom_hooks) of the course.
757
754
758
755
</div>
759
756
@@ -767,18 +764,18 @@ The application has a <i>Notification</i> component for displaying notifications
767
764
768
765
Implement the application's notification state management using the useReducer hook and context. The notification should tell the user when a new anecdote is created or an anecdote is voted on:
769
766
770
-

767
+

771
768
772
769
The notification is displayed for five seconds.
773
770
774
771
#### Exercise 6.24.
775
772
776
-
As stated in exercise 6.20, the server requires that the content of the anecdote to be added is at least 5 characters long. Now implement error handling for the insertion. In practice, it is sufficient to display a notification to the user in case of a failed POST request:
773
+
As stated in exercise 6.21, the server requires that the content of the anecdote to be added is at least 5 characters long. Now implement error handling for the insertion. In practice, it is sufficient to display a notification to the user in case of a failed POST request:
777
774
778
-

775
+

779
776
780
777
The error condition should be handled in the callback function registered for it, see
781
-
[here](https://react-query-v3.tanstack.com/reference/useMutation) how to register a function.
778
+
[here](https://tanstack.com/query/latest/docs/react/reference/useMutation) how to register a function.
782
779
783
780
This was the last exercise for this part of the course and it's time to push your code to GitHub and mark all of your completed exercises to the [exercise submission system](https://studies.cs.helsinki.fi/stats/courses/fullstackopen).
784
781
@@ -798,15 +795,14 @@ The situation may confuse a beginner and even an experienced web developer. Whic
798
795
799
796
For a simple application, <i>useState</i> is certainly a good starting point. If the application is communicating with the server, the communication can be handled in the same way as in chapters 1-5, using the state of the application itself. Recently, however, it has become more common to move the communication and associated state management at least partially under the control of React Query (or some other similar library). If you are concerned about useState and the prop drilling it entails, using context may be a good option. There are also situations where it may make sense to handle some of the state with useState and some with contexts.
800
797
801
-
The most comprehensive and robust state management solution is Redux, which is a way to implement the so-called [Flux](https://facebook.github.io/flux/) architecture. Redux is slightly older than the solutions presented in this section. The rigidity of Redux has been the motivation for many new state management solutions, such as React's <i>useReducer</i>. Some of the criticisms of Redux's rigidity have already become obsolete thanks to the [Redux Toolkit](https://redux-toolkit.js.org/).
798
+
The most comprehensive and robust state management solution is Redux, which is a way to implement the so-called [Flux](https://facebookarchive.github.io/flux/) architecture. Redux is slightly older than the solutions presented in this section. The rigidity of Redux has been the motivation for many new state management solutions, such as React's <i>useReducer</i>. Some of the criticisms of Redux's rigidity have already become obsolete thanks to the [Redux Toolkit](https://redux-toolkit.js.org/).
802
799
803
800
Over the years, there have also been other state management libraries developed that are similar to Redux, such as the newer entrant [Recoil](https://recoiljs.org/) and the slightly older [MobX](https://mobx.js.org/). However, according to [Npm trends](https://npmtrends.com/mobx-vs-recoil-vs-redux), Redux still clearly dominates, and in fact seems to be increasing its lead:
804
801
805
-

802
+

806
803
807
-
Also, Redux does not have to be used in its entirety in an application. It may make sense, for example, to manage the form state outside of Redux, especially in situations where the state of a form does not affect the rest of the application. It is also perfectly possible to use Redux and React Query together in the same application.
804
+
Also, Redux does not have to be used in its entirety in an application. It may make sense, for example, to manage the form state outside of Redux, especially in situations where the state of a form does not affect the rest of the application. It is also perfectly possible to use Redux and React Query together in the same application.
808
805
809
806
The question of which state management solution should be used is not at all straightforward. It is impossible to give a single correct answer. It is also likely that the selected state management solution may turn out to be suboptimal as the application grows to such an extent that the solution have to be changed even if the application has already been put into production use.
0 commit comments