Skip to content

Commit 238f95b

Browse files
authored
Merge pull request #3523 from pablo-maff/part6-spanish
Part6 spanish
2 parents b6026a1 + 61cda7c commit 238f95b

File tree

13 files changed

+536
-1249
lines changed

13 files changed

+536
-1249
lines changed

src/content/6/en/part6.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ lang: en
88

99
So far, we have placed the application's state and state logic directly inside React components. When applications grow larger, state management should be moved outside React components. In this part, we will introduce the Redux library, which is currently the most popular solution for managing the state of React applications.
1010

11-
We'll learn about the lightweight version of Redux directly supported by React, namely the React context and useRedux hook, as well as the React Query library that simplifies the server state management.
12-
11+
We'll learn about the lightweight version of Redux directly supported by React, namely the React context and useReducer hook, as well as the React Query library that simplifies the server state management.
1312

1413
<i>Part updated 23rd August 2023</i>
1514
- <i>Create React App replaced with Vite</i>

src/content/6/en/part6a.md

Lines changed: 33 additions & 36 deletions
Large diffs are not rendered by default.

src/content/6/en/part6b.md

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ We decide to implement the filter functionality by storing <i>the value of the f
8787
}
8888
```
8989

90-
Only the array of notes is stored in the state of the current implementation of our application. In the new implementation, the state object has two properties, <i>notes</i> that contains the array of notes and <i>filter</i> that contains a string indicating which notes should be displayed to the user.
90+
Only the array of notes was stored in the state of the previous implementation of our application. In the new implementation, the state object has two properties, <i>notes</i> that contains the array of notes and <i>filter</i> that contains a string indicating which notes should be displayed to the user.
9191

9292
### Combined reducers
9393

@@ -113,7 +113,7 @@ The actions for changing the state of the filter look like this:
113113
}
114114
```
115115

116-
Let's also create a new _action creator_ function. We will write the code for the action creator in a new <i>src/reducers/filterReducer.js</i> module:
116+
Let's also create a new _action creator_ function. We will write its code in a new <i>src/reducers/filterReducer.js</i> module:
117117

118118
```js
119119
const filterReducer = (state = 'ALL', action) => {
@@ -135,7 +135,6 @@ We can create the actual reducer for our application by combining the two existi
135135
Let's define the combined reducer in the <i>main.jsx</i> file:
136136

137137
```js
138-
import React from 'react'
139138
import ReactDOM from 'react-dom/client'
140139
import { createStore, combineReducers } from 'redux' // highlight-line
141140
import { Provider } from 'react-redux'
@@ -214,9 +213,9 @@ const filterReducer = (state = 'ALL', action) => {
214213

215214
Based on the console output one might get the impression that every action gets duplicated:
216215

217-
![devtools console output showing dupblicated actions in note and filter reducers](../../images/6/6.png)
216+
![devtools console output showing duplicated actions in note and filter reducers](../../images/6/6.png)
218217

219-
Is there a bug in our code? No. The combined reducer works in such a way that every <i>action</i> gets handled in <i>every</i> part of the combined reducer. Typically only one reducer is interested in any given action, but there are situations where multiple reducers change their respective parts of the state based on the same action.
218+
Is there a bug in our code? No. The combined reducer works in such a way that every <i>action</i> gets handled in <i>every</i> part of the combined reducer, or in other words, every reducer "listens" to all of the dispatched actions and does something with them if it has been instructed to do so. Typically only one reducer is interested in any given action, but there are situations where multiple reducers change their respective parts of the state based on the same action.
220219

221220
### Finishing the filters
222221

@@ -305,7 +304,7 @@ const VisibilityFilter = (props) => {
305304
export default VisibilityFilter
306305
```
307306

308-
With the new component <i>App</i> can be simplified as follows:
307+
With the new component, <i>App</i> can be simplified as follows:
309308

310309
```js
311310
import Notes from './components/Notes'
@@ -387,7 +386,7 @@ The current version of the application can be found on [GitHub](https://github.c
387386
388387
### Exercise 6.9
389388
390-
#### 6.9 Better anecdotes, step7
389+
#### 6.9 Better Anecdotes, step 7
391390
392391
Implement filtering for the anecdotes that are displayed to the user.
393392
@@ -433,7 +432,6 @@ npm install @reduxjs/toolkit
433432
Next, open the <i>main.jsx</i> file which currently creates the Redux store. Instead of Redux's <em>createStore</em> function, let's create the store using Redux Toolkit's [configureStore](https://redux-toolkit.js.org/api/configureStore) function:
434433
435434
```js
436-
import React from 'react'
437435
import ReactDOM from 'react-dom/client'
438436
import { Provider } from 'react-redux'
439437
import { configureStore } from '@reduxjs/toolkit' // highlight-line
@@ -460,7 +458,7 @@ ReactDOM.createRoot(document.getElementById('root')).render(
460458
)
461459
```
462460
463-
We already got rid of a few lines of code now that we don't need the <em>combineReducers</em> function to create the reducer for the store. We will soon see that the <em>configureStore</em> function has many additional benefits such as the effortless integration of development tools and many commonly used libraries without the need for additional configuration.
461+
We already got rid of a few lines of code, now we don't need the <em>combineReducers</em> function to create the store's reducer. We will soon see that the <em>configureStore</em> function has many additional benefits such as the effortless integration of development tools and many commonly used libraries without the need for additional configuration.
464462
465463
Let's move on to refactoring the reducers, which brings forth the benefits of the Redux Toolkit. With Redux Toolkit, we can easily create reducer and related action creators using the [createSlice](https://redux-toolkit.js.org/api/createSlice) function. We can use the <em>createSlice</em> function to refactor the reducer and action creators in the <i>reducers/noteReducer.js</i> file in the following manner:
466464
@@ -516,13 +514,15 @@ const noteSlice = createSlice({
516514
// highlight-end
517515
```
518516
519-
The <em>createSlice</em> function's <em>name</em> parameter defines the prefix which is used in the action's type values. For example, the <em>createNote</em> action defined later will have the type value of <em>notes/createNote</em>. It is a good practice to give the parameter a value which is unique among the reducers. This way there won't be unexpected collisions between the application's action type values. The <em>initialState</em> parameter defines the reducer's initial state. The <em>reducers</em> parameter takes the reducer itself as an object, of which functions handle state changes caused by certain actions. Note that the <em>action.payload</em> in the function contains the argument provided by calling the action creator:
517+
The <em>createSlice</em> function's <em>name</em> parameter defines the prefix which is used in the action's type values. For example, the <em>createNote</em> action defined later will have the type value of <em>notes/createNote</em>. It is a good practice to give the parameter a value which is unique among the reducers. This way there won't be unexpected collisions between the application's action type values.
518+
The <em>initialState</em> parameter defines the reducer's initial state.
519+
The <em>reducers</em> parameter takes the reducer itself as an object, of which functions handle state changes caused by certain actions. Note that the <em>action.payload</em> in the function contains the argument provided by calling the action creator:
520520
521521
```js
522522
dispatch(createNote('Redux Toolkit is awesome!'))
523523
```
524524
525-
This dispatch call responds to dispatching the following object:
525+
This dispatch call is equivalent to dispatching the following object:
526526
527527
```js
528528
dispatch({ type: 'notes/createNote', payload: 'Redux Toolkit is awesome!' })
@@ -544,7 +544,7 @@ createNote(state, action) {
544544
545545
We are mutating <em>state</em> argument's array by calling the <em>push</em> method instead of returning a new instance of the array. What's this all about?
546546
547-
Redux Toolkit utilizes the [Immer](https://immerjs.github.io/immer/) library with reducers created by <em>createSlice</em> function, which makes it possible to mutate the <em>state</em> argument inside the reducer. Immer uses the mutated state to produce a new, immutable state and thus the state changes remain immutable. Note that <em>state</em> can be changed without "mutating" it, as we have done with the <em>toggleImportanceOf</em> action. In this case, the function <i>returns</i> the new state. Nevertheless mutating the state will often come in handy especially when a complex state needs to be updated.
547+
Redux Toolkit utilizes the [Immer](https://immerjs.github.io/immer/) library with reducers created by <em>createSlice</em> function, which makes it possible to mutate the <em>state</em> argument inside the reducer. Immer uses the mutated state to produce a new, immutable state and thus the state changes remain immutable. Note that <em>state</em> can be changed without "mutating" it, as we have done with the <em>toggleImportanceOf</em> action. In this case, the function directly <i>returns</i> the new state. Nevertheless mutating the state will often come in handy especially when a complex state needs to be updated.
548548
549549
The <em>createSlice</em> function returns an object containing the reducer as well as the action creators defined by the <em>reducers</em> parameter. The reducer can be accessed by the <em>noteSlice.reducer</em> property, whereas the action creators by the <em>noteSlice.actions</em> property. We can produce the file's exports in the following way:
550550
@@ -655,9 +655,9 @@ The following is printed to the console
655655
656656
![devtools console showing Handler,Target as null but IsRevoked as true](../../images/6/40new.png)
657657
658-
The output is interesting but not very useful. This is about the previously mentioned Immer library used by the Redux Toolkit, which is now used internally to save the state of the Store.
658+
The output is interesting but not very useful. This is about the previously mentioned Immer library used by the Redux Toolkit internally to save the state of the Store.
659659
660-
The status can be converted to a human-readable format, e.g. by converting it to a string and back to a JavaScript object as follows:
660+
The status can be converted to a human-readable format, e.g. by converting it first to a string and then back to a JavaScript object as follows:
661661
662662
```js
663663
console.log(JSON.parse(JSON.stringify(state))) // highlight-line
@@ -671,13 +671,13 @@ Console output is now human readable
671671
672672
[Redux DevTools](https://chrome.google.com/webstore/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd) is a Chrome addon that offers useful development tools for Redux. It can be used for example to inspect the Redux store's state and dispatch actions through the browser's console. When the store is created using Redux Toolkit's <em>configureStore</em> function, no additional configuration is needed for Redux DevTools to work.
673673
674-
Once the addon is installed, clicking the <i>Redux</i> tab in the browser's console should open the development tools:
674+
Once the addon is installed, clicking the <i>Redux</i> tab in the browser's developer tools, the Redux DevTools should open:
675675
676676
![browser with redux addon in devtools](../../images/6/42new.png)
677677
678678
You can inspect how dispatching a certain action changes the state by clicking the action:
679679
680-
![devtools inspecting notes tree in redux](../../images/6/43new.png)
680+
![devtools inspecting state tree in redux](../../images/6/43new.png)
681681
682682
It is also possible to dispatch actions to the store using the development tools:
683683
@@ -693,19 +693,19 @@ You can find the code for our current application in its entirety in the <i>part
693693
694694
Let's continue working on the anecdote application using Redux that we started in exercise 6.3.
695695
696-
#### 6.10 Better anecdotes, step8
696+
#### 6.10 Better Anecdotes, step 8
697697
698698
Install Redux Toolkit for the project. Move the Redux store creation into the file <i>store.js</i> and use Redux Toolkit's <em>configureStore</em> to create the store.
699699
700700
Change the definition of the <i>filter reducer and action creators</i> to use the Redux Toolkit's <em>createSlice</em> function.
701701
702702
Also, start using Redux DevTools to debug the application's state easier.
703703
704-
#### 6.11 Better anecdotes, step9
704+
#### 6.11 Better Anecdotes, step 9
705705
706706
Change also the definition of the <i>anecdote reducer and action creators</i> to use the Redux Toolkit's <em>createSlice</em> function.
707707
708-
#### 6.12 Better anecdotes, step10
708+
#### 6.12 Better Anecdotes, step 10
709709
710710
The application has a ready-made body for the <i>Notification</i> component:
711711
@@ -750,7 +750,7 @@ You will have to make changes to the application's existing reducer. Create a se
750750
751751
The application does not have to use the <i>Notification</i> component intelligently at this point in the exercises. It is enough for the application to display the initial value set for the message in the <i>notificationReducer</i>.
752752
753-
#### 6.13 Better anecdotes, step11
753+
#### 6.13 Better Anecdotes, step 11
754754
755755
Extend the application so that it uses the <i>Notification</i> component to display a message for five seconds when the user votes for an anecdote or creates a new anecdote:
756756

src/content/6/en/part6c.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -329,21 +329,21 @@ The current state of the code for the application can be found on [GitHub](https
329329

330330
### Exercises 6.14.-6.15.
331331

332-
#### 6.14 Anecdotes and the backend, step1
332+
#### 6.14 Anecdotes and the Backend, step 1
333333

334334
When the application launches, fetch the anecdotes from the backend implemented using json-server.
335335

336336
As the initial backend data, you can use, e.g. [this](https://github.com/fullstack-hy2020/misc/blob/master/anecdotes.json).
337337

338-
#### 6.15 Anecdotes and the backend, step2
338+
#### 6.15 Anecdotes and the Backend, step 2
339339

340340
Modify the creation of new anecdotes, so that the anecdotes are stored in the backend.
341341

342342
</div>
343343

344344
<div class="content">
345345

346-
### Asynchronous actions and Redux thunk
346+
### Asynchronous actions and Redux Thunk
347347

348348
Our approach is quite good, but it is not great that the communication with the server happens inside the functions of the components. It would be better if the communication could be abstracted away from the components so that they don't have to do anything else but call the appropriate <i>action creator</i>. As an example, <i>App</i> would initialize the state of the application as follows:
349349

@@ -376,7 +376,7 @@ const NewNote = () => {
376376
}
377377
```
378378

379-
In this implementation, both components would dispatch an action without the need to know about the communication between the server that happens behind the scenes. These kinds of <i>async actions</i> can be implemented using the [Redux Thunk](https://github.com/reduxjs/redux-thunk) library. The use of the library doesn't need any additional configuration or even installation when the Redux store is created using the Redux Toolkit's <em>configureStore</em> function.
379+
In this implementation, both components would dispatch an action without the need to know about the communication with the server that happens behind the scenes. These kinds of <i>async actions</i> can be implemented using the [Redux Thunk](https://github.com/reduxjs/redux-thunk) library. The use of the library doesn't need any additional configuration or even installation when the Redux store is created using the Redux Toolkit's <em>configureStore</em> function.
380380

381381
With Redux Thunk it is possible to implement <i>action creators</i> which return a function instead of an object. The function receives Redux store's <em>dispatch</em> and <em>getState</em> methods as parameters. This allows for example implementations of asynchronous action creators, which first wait for the completion of a certain asynchronous operation and after that dispatch some action, which changes the store's state.
382382

@@ -557,19 +557,19 @@ Redux Toolkit offers a multitude of tools to simplify asynchronous state managem
557557

558558
### Exercises 6.16.-6.19.
559559

560-
#### 6.16 Anecdotes and the backend, step3
560+
#### 6.16 Anecdotes and the Backend, step 3
561561

562562
Modify the initialization of the Redux store to happen using asynchronous action creators, which are made possible by the Redux Thunk library.
563563

564-
#### 6.17 Anecdotes and the backend, step4
564+
#### 6.17 Anecdotes and the Backend, step 4
565565

566566
Also modify the creation of a new anecdote to happen using asynchronous action creators, made possible by the Redux Thunk library.
567567

568-
#### 6.18 Anecdotes and the backend, step5
568+
#### 6.18 Anecdotes and the Backend, step 5
569569

570570
Voting does not yet save changes to the backend. Fix the situation with the help of the Redux Thunk library.
571571

572-
#### 6.19 Anecdotes and the backend, step6
572+
#### 6.19 Anecdotes and the Backend, step 6
573573

574574
The creation of notifications is still a bit tedious since one has to do two actions and use the _setTimeout_ function:
575575

0 commit comments

Comments
 (0)