Skip to content

Commit ef84891

Browse files
committed
update en/part6d.md and en/part6e.md
1 parent 85f1a41 commit ef84891

File tree

2 files changed

+61
-72
lines changed

2 files changed

+61
-72
lines changed

src/content/6/en/part6d.md

Lines changed: 25 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ The initial code is on GitHub in the repository [https://github.com/fullstack-hy
5050

5151
### Managing data on the server with the React Query library
5252

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.
5454

5555
Install the library with the command
5656

@@ -60,7 +60,6 @@ npm install react-query
6060

6161
A few additions to the file <i>index.js</i> are needed to pass the library functions to the entire application:
6262

63-
6463
```js
6564
import React from 'react'
6665
import ReactDOM from 'react-dom/client'
@@ -109,15 +108,15 @@ const App = () => {
109108
}
110109
```
111110

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.
113112

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:
115114

116-
![](../../images/6/60new.png)
115+
![browser devtools showing success status](../../images/6/60new.png)
117116

118117
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:
119118

120-
```
119+
```html
121120
<div>loading data...</div>
122121
```
123122

@@ -190,7 +189,7 @@ const App = () => {
190189
}
191190
```
192191

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):
194193

195194
```js
196195
const newNoteMutation = useMutation(createNote)
@@ -200,14 +199,13 @@ The parameter is the function we added to the file <i>requests.js</i>, which use
200199

201200
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:
202201

203-
204202
```js
205203
newNoteMutation.mutate({ content, important: true })
206204
```
207205

208206
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.
209207

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).
211209

212210
Fortunately, invalidation is easy, it can be done by defining the appropriate <i>onSuccess</i> callback function to the mutation:
213211

@@ -284,11 +282,11 @@ The application works well, and the code is relatively simple. The ease of makin
284282

285283
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:
286284

287-
![](../../images/6/61new.png)
285+
![devtools network tab with highlight over 3 and notes requests](../../images/6/61new.png)
288286

289287
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.
290288

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.
292290

293291
The change for the mutation adding a new note is as follows:
294292

@@ -317,9 +315,9 @@ It would be relatively easy to make a similar change to a mutation that changes
317315

318316
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:
319317

320-
![](../../images/6/62new.png)
318+
![dev tools notes app with input text field highlighted and arrow on network over notes request as 200](../../images/6/62new.png)
321319

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:
323321

324322
```js
325323
const App = () => {
@@ -336,14 +334,14 @@ If you put a console.log statement to the code, you can see from browser console
336334

337335
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>.
338336

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
340338

341339
- React Query is a <i>server-state library</i>, responsible for managing asynchronous operations between your server and client
342340
- 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
343341

344342
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.
345343

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.
347345

348346
</div>
349347

@@ -359,13 +357,12 @@ Implement retrieving anecdotes from the server using React Query.
359357

360358
The application should work in such a way that if there are problems communicating with the server, only an error page will be displayed:
361359

362-
![](../../images/6/65new.png)
360+
![browser saying anecdote service not available due to problems in server on localhost](../../images/6/65new.png)
363361

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.
365363

366364
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:
367365

368-
369366
```js
370367
const result = useQuery(
371368
'anecdotes', getAnecdotes,
@@ -392,7 +389,7 @@ Implement adding new anecdotes to the server using React Query. The application
392389

393390
#### Exercise 6.22
394391

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.
396393

397394
</div>
398395

@@ -404,7 +401,7 @@ So even if the application uses React Query, some kind of solution is usually ne
404401

405402
Let's look at a simple counter application. The application displays the counter value, and offers three buttons to update the counter status:
406403

407-
![](../../images/6/63new.png)
404+
![browser showing + - 0 buttons and 7 above](../../images/6/63new.png)
408405

409406
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:
410407

@@ -753,7 +750,7 @@ The solution is quite elegant. The entire state of the application, i.e. the val
753750

754751
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>.
755752

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.
757754

758755
</div>
759756

@@ -767,18 +764,18 @@ The application has a <i>Notification</i> component for displaying notifications
767764

768765
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:
769766

770-
![](../../images/6/66new.png)
767+
![browser showing notification for added anecdote](../../images/6/66new.png)
771768

772769
The notification is displayed for five seconds.
773770

774771
#### Exercise 6.24.
775772

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:
777774

778-
![](../../images/6/67new.png)
775+
![browser showing error notification for trying to add too short of an anecdoate](../../images/6/67new.png)
779776

780777
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.
782779

783780
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).
784781

@@ -798,15 +795,14 @@ The situation may confuse a beginner and even an experienced web developer. Whic
798795

799796
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.
800797

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/).
802799

803800
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:
804801

805-
![](../../images/6/64new.png)
802+
![graph showing redux growing in popularity over past 5 years](../../images/6/64new.png)
806803

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.
808805

809806
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.
810807

811808
</div>
812-

0 commit comments

Comments
 (0)