Skip to content

Commit 86b8b9f

Browse files
committed
part 6c
1 parent e3fa2d6 commit 86b8b9f

File tree

3 files changed

+48
-98
lines changed

3 files changed

+48
-98
lines changed

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

src/content/6/es/part6c.md

Lines changed: 38 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,8 @@ lang: es
77

88
<div class="content">
99

10-
1110
Expandamos la aplicación, de modo que las notas se almacenen en el backend. Usaremos [json-server](/es/part2/obteniendo_datos_del_servidor), de la parte 2.
1211

13-
1412
El estado inicial de la base de datos se almacena en el archivo <i>db.json</i>, que se coloca en la raíz del proyecto:
1513

1614
```json
@@ -30,17 +28,13 @@ El estado inicial de la base de datos se almacena en el archivo <i>db.json</i>,
3028
}
3129
```
3230

33-
34-
35-
Instalaremos json-server para el proyecto...
31+
Instalaremos json-server en nuestro proyecto...
3632

3733
```js
3834
npm install json-server --save-dev
3935
```
4036

41-
42-
43-
y agregue la siguiente línea a la parte de <i>scripts</i> del archivo <i>package.json</i>
37+
y agregaremos la siguiente línea a la parte de <i>scripts</i> del archivo <i>package.json</i>
4438

4539
```js
4640
"scripts": {
@@ -127,7 +121,7 @@ export const { createNote, toggleImportanceOf, appendNote } = noteSlice.actions
127121
export default noteSlice.reducer
128122
```
129123

130-
Una manera rápida para inicializar el estado de las notas basado en los datos recibidos del backend es extraer las notas en el archivo <i>index.js</i> y enviar (dispatch) una acción usando <em>appendNote</em> para cada nota individual:
124+
Una manera rápida para inicializar el estado de las notas basado en los datos recibidos del backend es extraer las notas en el archivo <i>main.jsx</i> y enviar (dispatch) una acción usando el action creator <em>appendNote</em> para cada objeto de nota:
131125

132126
```js
133127
// ...
@@ -152,7 +146,7 @@ noteService.getAll().then(notes =>
152146
// ...
153147
```
154148

155-
Enviar (dispatching) múltiples acciones no es práctico. Agreguemos un creador de acciones <em>setNotes</em> que se puede usar para reemplazar directamente el array de notas. Obtendremos el creador de acciones de la función <em>createSlice</em> implementando la acción <em>setNotes</em>:
149+
Enviar (dispatching) múltiples acciones no parece muy práctico. Agreguemos un action creator <em>setNotes</em> que se pueda usar para reemplazar directamente al array de notas. Obtendremos al action creator de la función <em>createSlice</em> implementando la acción <em>setNotes</em>:
156150

157151
```js
158152
// ...
@@ -200,7 +194,7 @@ export const { createNote, toggleImportanceOf, appendNote, setNotes } = noteSlic
200194
export default noteSlice.reducer
201195
```
202196

203-
Ahora, el código en el archivo <i>index.js</i> se ve mucho mejor:
197+
Ahora, el código en el archivo <i>main.jsx</i> se ve mucho mejor:
204198

205199
```js
206200
// ...
@@ -219,11 +213,11 @@ noteService.getAll().then(notes =>
219213
)
220214
```
221215

222-
> **NB:** ¿por qué no usamos await en lugar de promesas y controladores de eventos?
216+
> **NB:** ¿Por qué no usamos await en lugar de promesas y controladores de eventos?
223217
>
224-
>Await solo funciona dentro de funciones <i>async</i>, y el código en <i>index.js</i> no está dentro de una función, por lo que debido a la naturaleza simple de la operación, esta vez nos abstendremos de usar <i>async</i>.
218+
>Await solo funciona dentro de funciones <i>async</i>, y el código en <i>main.jsx</i> no está dentro de una función, por lo que debido a la naturaleza simple de la operación, esta vez nos abstendremos de usar <i>async</i>.
225219
226-
Sin embargo, decidimos mover la inicialización de las notas al componente <i>App</i> y, como es habitual al obtener datos de un servidor, usaremos <i>effect hook</i>.
220+
Sin embargo, decidimos mover la inicialización de las notas al componente <i>App</i> y, como es habitual al obtener datos de un servidor, usaremos el <i>effect hook</i>.
227221

228222
```js
229223
import { useEffect } from 'react' // highlight-line
@@ -255,47 +249,6 @@ const App = () => {
255249
export default App
256250
```
257251

258-
El uso del hook useEffect genera una advertencia eslint:
259-
260-
![vscode warnig useEffect missing dispatch dependency](../../images/6/26ea.png)
261-
262-
Podemos deshacernos de él haciendo lo siguiente:
263-
264-
```js
265-
const App = () => {
266-
const dispatch = useDispatch()
267-
useEffect(() => {
268-
noteService
269-
.getAll().then(notes => dispatch(setNotes(notes)))
270-
}, [dispatch]) // highlight-line
271-
272-
// ...
273-
}
274-
```
275-
276-
Ahora, la variable dispatch que definimos en el componente _App_, que prácticamente es la función de dispatch de redux-store, se ha agregado al array que recibe useEffect como parámetro.
277-
**Si** el valor de la variable dispatch cambiara durante el tiempo de ejecución, el efecto se ejecutaría nuevamente. Sin embargo, esto no puede suceder en nuestra aplicación, por lo que la advertencia es innecesaria.
278-
279-
Otra forma de deshacerse de la advertencia sería deshabilitar eslint en esa línea:
280-
281-
```js
282-
const App = () => {
283-
const dispatch = useDispatch()
284-
useEffect(() => {
285-
noteService
286-
.getAll().then(notes => dispatch(setNotes(notes)))
287-
// highlight-start
288-
}, []) // eslint-disable-line react-hooks/exhaustive-deps
289-
// highlight-end
290-
291-
// ...
292-
}
293-
```
294-
295-
Generalmente, deshabilitar eslint cuando genera una advertencia no es una buena idea. Aunque la regla eslint en cuestión ha causado algunos [argumentos](https://github.com/facebook/create-react-app/issues/6880), usaremos la primera solución.
296-
297-
Se encuentra más información sobre la necesidad de definir las dependencias de los hooks en la [documentación de react](https://reactjs.org/docs/hooks-faq.html#is-it-safe-to-omit-functions-from-the-list-of-dependencies).
298-
299252
### Enviando datos al backend
300253

301254
Podemos hacer lo mismo cuando se trata de crear una nueva nota. Expandamos el código comunicándonos con el servidor de la siguiente manera:
@@ -351,7 +304,7 @@ const NewNote = (props) => {
351304
export default NewNote
352305
```
353306

354-
Debido a que el backend genera ids para las notas, cambiaremos el creador de la acción <em>createNote</em> en el archivo <i>noteReducer.js</i> de la siguiente manera:
307+
Debido a que el backend genera ids para las notas, cambiaremos el action creator <em>createNote</em> en el archivo <i>noteReducer.js</i> de la siguiente manera:
355308

356309
```js
357310
const noteSlice = createSlice({
@@ -366,42 +319,41 @@ const noteSlice = createSlice({
366319
})
367320
```
368321

369-
El cambio de importancia de las notas podría implementarse utilizando el mismo principio, lo que significa realizar una llamada de método asincrónico al servidor y luego enviar una acción apropiada.
322+
El cambio de importancia de las notas podría implementarse utilizando el mismo principio, haciendo una llamada asíncrona al servidor y luego enviando una acción apropiada.
370323

371-
El estado actual del código para la aplicación se puede encontrar en [Github](https://github.com/fullstack-hy2020/redux-notes/tree/part6-3) en la rama <i>part6-3</i>.
324+
El estado actual del código para la aplicación se puede encontrar en [GitHub](https://github.com/fullstack-hy2020/redux-notes/tree/part6-3) en la rama <i>part6-3</i>.
372325

373326
</div>
374327

375328
<div class="tasks">
376329

377330
### Ejercicios 6.14.-6.15.
378331

379-
#### 6.14 Anécdotas y el backend, paso 1
380-
381-
Cuando la aplicación se inicie, obtenga las anécdotas del backend implementado usando json-server.
332+
#### 6.14 Anécdotas y el Backend, paso 1
382333

383-
Como datos de backend iniciales, puede usar, por ejemplo, [esto](https://github.com/fullstack-hy2020/misc/blob/master/anecdotes.json).
334+
Cuando la aplicación se inicie, obtén las anécdotas del backend implementado usando json-server.
384335

336+
Como datos de backend iniciales, puedes usar, por ejemplo, [esto](https://github.com/fullstack-hy2020/misc/blob/master/anecdotes.json).
385337

386-
#### 6.15 Anécdotas y el backend, paso 2
338+
#### 6.15 Anécdotas y el Backend, paso 2
387339

388-
Modificar la creación de nuevas anécdotas, de forma que las anécdotas se almacenen en el backend.
340+
Modifica la creación de nuevas anécdotas, de forma que las anécdotas se almacenen en el backend.
389341

390342
</div>
391343

392344
<div class="content">
393345

394-
### Acciones asincrónicas y redux thunk
346+
### Acciones asíncronas y Redux Thunk
395347

396-
Nuestro enfoque es bastante bueno, pero no es genial que la comunicación con el servidor suceda dentro de las funciones de los componentes. Sería mejor si la comunicación pudiera abstraerse de los componentes para que no tengan que hacer nada más que llamar al creador de acciones apropiado. Como ejemplo, <i>App</i> inicializaría el estado de la aplicación de la siguiente manera:
348+
Nuestro enfoque es bastante bueno, pero no es muy bueno que la comunicación con el servidor suceda dentro de las funciones de los componentes. Sería mejor si la comunicación pudiera abstraerse de los componentes para que no tengan que hacer nada más que llamar al action creator apropiado. Como ejemplo, <i>App</i> inicializaría el estado de la aplicación de la siguiente manera:
397349

398350
```js
399351
const App = () => {
400352
const dispatch = useDispatch()
401353

402354
useEffect(() => {
403355
dispatch(initializeNotes())
404-
}, [dispatch])
356+
}, [])
405357

406358
// ...
407359
}
@@ -424,11 +376,11 @@ const NewNote = () => {
424376
}
425377
```
426378

427-
En esta implementación, ambos componentes enviarían una acción sin necesidad de saber sobre la comunicación entre el servidor que sucede detrás de escena. Estos tipos de <i>acciones asincrónicas</i> se pueden implementar utilizando la librería [Redux Thunk](https://github.com/reduxjs/redux-thunk). El uso de la librería no requiere ninguna configuración adicional o incluso instalación cuando el store de Redux se crea utilizando la función <em>configureStore</em> del kit de herramientas de Redux (Redux Toolkit).
379+
En esta implementación, ambos componentes enviarían una acción sin necesidad de saber sobre la comunicación con el servidor que sucede detrás de escena. Estos tipos de <i>acciones asíncronas</i> se pueden implementar utilizando la librería [Redux Thunk](https://github.com/reduxjs/redux-thunk). El uso de la librería no requiere ninguna configuración adicional o incluso instalación cuando el store de Redux se ha creado utilizando la función <em>configureStore</em> del kit de herramientas de Redux (Redux Toolkit).
428380

429-
Con Redux Thunk, es posible implementar <i>action creators</i> que devuelven una función en lugar de un objeto. La función recibe los métodos <em>dispatch</em> y <em>getState</em> del store de Redux como parámetros. Esto permite, por ejemplo, implementaciones de creadores de acciones asincrónicas, que primero esperan la finalización de una cierta operación asincrónica y luego despachan alguna acción, que cambia el estado del store.
381+
Con Redux Thunk, es posible implementar <i>action creators</i> que devuelven una función en lugar de un objeto. La función recibe los métodos <em>dispatch</em> y <em>getState</em> del store de Redux como parámetros. Esto permite, por ejemplo, implementaciones de action creators asíncronos, que primero esperan la finalización de una cierta operación asíncrona y luego despachan alguna acción, que cambia el estado del store.
430382

431-
Podemos implementar el <i>action creator</i> <em>initializeNotes</em> que inicializa las notas basadas en los datos recibidos del servidor de la siguiente manera:
383+
Podemos implementar un action creator <em>initializeNotes</em> que inicializa las notas basadas en los datos recibidos del servidor de la siguiente manera:
432384

433385
```js
434386
// ...
@@ -450,7 +402,7 @@ export const initializeNotes = () => {
450402
export default noteSlice.reducer
451403
```
452404

453-
En la función interna, es decir, la <i>acción asincrónica</i>, la operación primero obtiene todas las notas del servidor y luego <i>despacha</i> la acción <em>setNotes</em>, que las agrega al store.
405+
En la función interna, es decir, la <i>acción asíncrona</i>, la operación primero obtiene todas las notas del servidor y luego <i>despacha</i> la acción <em>setNotes</em>, que las agrega al store.
454406

455407
El componente <i>App</i> puede inicializar las notas de la siguiente manera:
456408

@@ -464,7 +416,7 @@ const App = () => {
464416
// highlight-start
465417
useEffect(() => {
466418
dispatch(initializeNotes())
467-
}, [dispatch])
419+
}, [])
468420
// highlight-end
469421

470422
return (
@@ -479,7 +431,7 @@ const App = () => {
479431

480432
La solución es bastante elegante. La lógica de inicialización de las notas se ha separado completamente del componente React.
481433

482-
Ahora, reemplacemos el creador de acciones <em>createNote</em> creado por la función <em>createSlice</em> con un creador de acciones asincrónico:
434+
Ahora, reemplacemos el action creator <em>createNote</em> creado por la función <em>createSlice</em> con un action creator asíncrono:
483435

484436
```js
485437
// ...
@@ -534,7 +486,7 @@ export const createNote = content => {
534486
export default noteSlice.reducer
535487
```
536488

537-
El principio aquí es el mismo: primero se ejecuta una operación asincrónica y luego se <i>despacha</i> la acción que cambia el estado del store.
489+
El principio aquí es el mismo: primero se ejecuta una operación asíncrona y luego se <i>despacha</i> la acción que cambia el estado del store.
538490

539491
El componente <i>NewNote</i> cambia como se muestra a continuación:
540492

@@ -561,7 +513,7 @@ const NewNote = () => {
561513
}
562514
```
563515

564-
Finalmente, limpiemos un poco el archivo <i>index.js</i> moviendo el código relacionado con la creación del store de Redux a su propio archivo <i>store.js</i>:
516+
Finalmente, limpiemos un poco el archivo <i>main.jsx</i> moviendo el código relacionado con la creación del store de Redux a su propio archivo <i>store.js</i>:
565517

566518
```js
567519
import { configureStore } from '@reduxjs/toolkit'
@@ -579,7 +531,7 @@ const store = configureStore({
579531
export default store
580532
```
581533

582-
Despues de los cambios, el contenido del archivo <i>index.js</i> es el siguiente:
534+
Luego de los cambios, el contenido del archivo <i>main.jsx</i> es el siguiente:
583535

584536
```js
585537
import React from 'react'
@@ -603,23 +555,21 @@ Redux Toolkit ofrece una gran cantidad de herramientas para simplificar la admin
603555

604556
<div class="tasks">
605557

606-
607558
### Ejercicios 6.16.-6.19.
608559

609-
#### 6.16 Anécdotas y el backend, paso 3
610-
611-
Modifique la inicialización de la redux-store para que suceda utilizando creadores de acciones asincrónicas, que son posibles gracias a la librería <i>redux-thunk</i>.
560+
#### 6.16 Anécdotas y el Backend, paso 3
612561

613-
#### 6.17 Anécdotas y el backend, paso 4
562+
Modifica la inicialización de la store de Redux para que suceda utilizando action creators asíncronos, los cuales son posibles gracias a la librería Redux Thunk.
614563

615-
También modifique la creación de una nueva anécdota para que suceda usando creadores de acciones asincrónicas, hecho posible por la librería <i>redux-thunk</i>.
564+
#### 6.17 Anécdotas y el Backend, paso 4
616565

566+
También modifica la creación de una nueva anécdota para que suceda usando action creators asíncronos, hecho posible por la librería Redux Thunk.
617567

618-
#### 6.18 Anécdotas y el backend, paso 5
568+
#### 6.18 Anécdotas y el Backend, paso 5
619569

620-
La votación aún no guarda los cambios en el backend. Arregle la situación con la ayuda de la librería <i>redux-thunk</i>.
570+
La votación aún no guarda los cambios en el backend. Arregla la situación con la ayuda de la librería Redux Thunk.
621571

622-
#### 6.19 Anécdotas y el backend, paso 6
572+
#### 6.19 Anécdotas y el Backend, paso 6
623573

624574
La creación de notificaciones sigue siendo un poco tediosa, ya que hay que realizar dos acciones y utilizar la función _setTimeout_:
625575

@@ -630,14 +580,14 @@ setTimeout(() => {
630580
}, 5000)
631581
```
632582

633-
Cree un creador de acciones asincrónicas, que le permite a uno proporcionar la notificación de la siguiente manera:
583+
Crea un action creator, que te permita proveer la notificación de la siguiente manera:
634584

635585
```js
636586
dispatch(setNotification(`you voted '${anecdote.content}'`, 10))
637587
```
638588

639-
el primer parámetro es el texto que se representará y el segundo parámetro es el tiempo para mostrar la notificación dada en segundos.
589+
El primer parámetro es el texto que sera renderizado y el segundo parámetro es el tiempo durante el cual se mostrara la notificación en segundos.
640590

641-
Implemente el uso de esta notificación mejorada en su aplicación.
591+
Implementa el uso de esta notificación mejorada en tu aplicación.
642592

643593
</div>

0 commit comments

Comments
 (0)