Skip to content

Commit 5eb5ce8

Browse files
committed
Content and Translation corrections
1 parent 556a1cb commit 5eb5ce8

File tree

2 files changed

+136
-56
lines changed

2 files changed

+136
-56
lines changed

src/content/6/en/part6c.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ const NewNote = (props) => {
346346
export default NewNote
347347
```
348348

349-
Because the backend generates ids for the notes, we'll change the action creator <em>createNote</em> in the file <i>createNote</i> accordingly:
349+
Because the backend generates ids for the notes, we'll change the action creator <em>createNote</em> in the file <i>noteReducer.js</i> accordingly:
350350

351351
```js
352352
const noteSlice = createSlice({

src/content/6/es/part6c.md

Lines changed: 135 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ y agregue la siguiente línea a la parte de <i>scripts</i> del archivo <i>packag
5151

5252
Ahora iniciemos json-server con el comando _npm run server_.
5353

54+
### Obteniendo datos del backend
55+
5456
A continuación, crearemos un método en el archivo <i>services/notes.js</i>, que usa <i>axios</i> para obtener datos del backend
5557

5658
```js
@@ -75,96 +77,169 @@ npm install axios
7577
Cambiaremos la inicialización del estado en <i>noteReducer</i>, de modo que por defecto no haya notas:
7678

7779
```js
78-
const noteReducer = (state = [], action) => {
80+
const noteSlice = createSlice({
81+
name: 'notes',
82+
initialState: [], // highlight-line
7983
// ...
80-
}
84+
})
85+
```
86+
87+
También agreguemos una nueva acción <em>appendNote</em> para añadir un objeto de una nota:
88+
89+
```js
90+
const noteSlice = createSlice({
91+
name: 'notes',
92+
initialState: [],
93+
reducers: {
94+
createNote(state, action) {
95+
const content = action.payload
96+
97+
state.push({
98+
content,
99+
important: false,
100+
id: generateId(),
101+
})
102+
},
103+
toggleImportanceOf(state, action) {
104+
const id = action.payload
105+
106+
const noteToChange = state.find(n => n.id === id)
107+
108+
const changedNote = {
109+
...noteToChange,
110+
important: !noteToChange.important
111+
}
112+
113+
return state.map(note =>
114+
note.id !== id ? note : changedNote
115+
)
116+
},
117+
// highlight-start
118+
appendNote(state, action) {
119+
state.push(action.payload)
120+
}
121+
// highlight-end
122+
},
123+
})
124+
125+
export const { createNote, toggleImportanceOf, appendNote } = noteSlice.actions // highlight-line
126+
127+
export default noteSlice.reducer
81128
```
82129

83-
Una forma rápida de inicializar el estado en función de los datos en el servidor es buscar las notas en el archivo <i>index.js</i> y enviar la acción <i>NEW\_NOTE</i> para cada una de ellas:
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:
84131

85132
```js
86133
// ...
87134
import noteService from './services/notes' // highlight-line
135+
import noteReducer, { appendNote } from './reducers/noteReducer' // highlight-line
88136

89-
const reducer = combineReducers({
90-
notes: noteReducer,
91-
filter: filterReducer,
137+
const store = configureStore({
138+
reducer: {
139+
notes: noteReducer,
140+
filter: filterReducer,
141+
}
92142
})
93143

94-
const store = createStore(reducer)
95-
96144
// highlight-start
97145
noteService.getAll().then(notes =>
98146
notes.forEach(note => {
99-
store.dispatch({ type: 'NEW_NOTE', data: note })
147+
store.dispatch(appendNote(note))
100148
})
101149
)
102150
// highlight-end
103151

104152
// ...
105153
```
106154

107-
108-
109-
Agreguemos soporte en el reducer para la acción <i>INIT\_NOTES</i>, con el cual se puede realizar la inicialización enviando una sola acción. Creemos también una función de creador de acciones _initializeNotes_.
155+
Enviar (dispatching) múltiples acciones parece un poco imprá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>:
110156

111157
```js
112158
// ...
113-
const noteReducer = (state = [], action) => {
114-
console.log('ACTION:', action)
115-
switch (action.type) {
116-
case 'NEW_NOTE':
117-
return [...state, action.data]
118-
case 'INIT_NOTES': // highlight-line
119-
return action.data // highlight-line
120-
// ...
121-
}
122-
}
123159

124-
export const initializeNotes = (notes) => {
125-
return {
126-
type: 'INIT_NOTES',
127-
data: notes,
128-
}
129-
}
160+
const noteSlice = createSlice({
161+
name: 'notes',
162+
initialState: [],
163+
reducers: {
164+
createNote(state, action) {
165+
const content = action.payload
166+
167+
state.push({
168+
content,
169+
important: false,
170+
id: generateId(),
171+
})
172+
},
173+
toggleImportanceOf(state, action) {
174+
const id = action.payload
130175

131-
// ...
132-
```
176+
const noteToChange = state.find(n => n.id === id)
133177

178+
const changedNote = {
179+
...noteToChange,
180+
important: !noteToChange.important
181+
}
134182

135-
<i>index.js</i> simplifica:
183+
return state.map(note =>
184+
note.id !== id ? note : changedNote
185+
)
186+
},
187+
appendNote(state, action) {
188+
state.push(action.payload)
189+
},
190+
// highlight-start
191+
setNotes(state, action) {
192+
return action.payload
193+
}
194+
// highlight-end
195+
},
196+
})
197+
198+
export const { createNote, toggleImportanceOf, appendNote, setNotes } = noteSlice.actions // highlight-line
199+
200+
export default noteSlice.reducer
201+
```
202+
203+
Ahora, el código en el archivo <i>index.js</i> se ve mucho mejor:
136204

137205
```js
138-
import noteReducer, { initializeNotes } from './reducers/noteReducer'
139206
// ...
207+
import noteService from './services/notes'
208+
import noteReducer, { setNotes } from './reducers/noteReducer' // highlight-line
209+
210+
const store = configureStore({
211+
reducer: {
212+
notes: noteReducer,
213+
filter: filterReducer,
214+
}
215+
})
140216

141217
noteService.getAll().then(notes =>
142-
store.dispatch(initializeNotes(notes))
218+
store.dispatch(setNotes(notes)) // highlight-line
143219
)
144220
```
145221

146-
147222
> **NB:** ¿por qué no usamos await en lugar de promesas y controladores de eventos (registrados en _then_ métodos)?
148223
>
149224
>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>.
150225
151226
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>.
152227

153228
```js
154-
import React, {useEffect} from 'react' // highlight-line
229+
import { useEffect } from 'react' // highlight-line
155230
import NewNote from './components/NewNote'
156231
import Notes from './components/Notes'
157232
import VisibilityFilter from './components/VisibilityFilter'
158-
import noteService from './services/notes'
159-
import { initializeNotes } from './reducers/noteReducer' // highlight-line
233+
import noteService from './services/notes' // highlight-line
234+
import { setNotes } from './reducers/noteReducer' // highlight-line
160235
import { useDispatch } from 'react-redux' // highlight-line
161236

162237
const App = () => {
238+
// highlight-start
163239
const dispatch = useDispatch()
164-
// highlight-start
165240
useEffect(() => {
166241
noteService
167-
.getAll().then(notes => dispatch(initializeNotes(notes)))
242+
.getAll().then(notes => dispatch(setNotes(notes)))
168243
}, [])
169244
// highlight-end
170245

@@ -182,7 +257,7 @@ export default App
182257

183258
El uso del hoook useEffect genera una advertencia eslint:
184259

185-
![](../../images/6/26ea.png)
260+
![vscode warnig useEffect missing dispatch dependency](../../images/6/26ea.png)
186261

187262
Podemos deshacernos de él haciendo lo siguiente:
188263

@@ -191,7 +266,7 @@ const App = () => {
191266
const dispatch = useDispatch()
192267
useEffect(() => {
193268
noteService
194-
.getAll().then(notes => dispatch(initializeNotes(notes)))
269+
.getAll().then(notes => dispatch(setNotes(notes)))
195270
}, [dispatch]) // highlight-line
196271

197272
// ...
@@ -208,9 +283,9 @@ const App = () => {
208283
const dispatch = useDispatch()
209284
useEffect(() => {
210285
noteService
211-
.getAll().then(notes => dispatch(initializeNotes(notes)))
286+
.getAll().then(notes => dispatch(setNotes(notes)))
212287
// highlight-start
213-
},[]) // eslint-disable-line react-hooks/exhaustive-deps
288+
}, []) // eslint-disable-line react-hooks/exhaustive-deps
214289
// highlight-end
215290

216291
// ...
@@ -221,6 +296,8 @@ Generalmente, deshabilitar eslint cuando genera una advertencia no es una buena
221296

222297
Más 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).
223298

299+
### Enviando datos al backend
300+
224301
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:
225302

226303
```js
@@ -248,7 +325,6 @@ export default {
248325
El método _addNote_ del componente <i>NewNote</i> cambia ligeramente:
249326

250327
```js
251-
import React from 'react'
252328
import { useDispatch } from 'react-redux'
253329
import { createNote } from '../reducers/noteReducer'
254330
import noteService from '../services/notes' // highlight-line
@@ -275,35 +351,39 @@ const NewNote = (props) => {
275351
export default NewNote
276352
```
277353

278-
Debido a que el backend genera ids para las notas, cambiaremos el creador de la acción _createNote_
354+
Debido a que el backend genera ids para las notas, cambiaremos el creador de la acción <em>createNote</em> en el archoivo <i>noteReducer.js</i> de la siguiente manera:
279355

280356
```js
281-
export const createNote = (data) => {
282-
return {
283-
type: 'NEW_NOTE',
284-
data,
285-
}
286-
}
357+
const noteSlice = createSlice({
358+
name: 'notes',
359+
initialState: [],
360+
reducers: {
361+
createNote(state, action) {
362+
state.push(action.payload) // highlight-line
363+
},
364+
// ..
365+
},
366+
})
287367
```
288368

289369
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.
290370

291-
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>.
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>.
292372

293373
</div>
294374

295375
<div class="tasks">
296376

297-
### Ejercicios 6.13.-6.14.
377+
### Ejercicios 6.14.-6.15.
298378

299-
#### 6.13 Anécdotas y el backend, paso 1
379+
#### 6.14 Anécdotas y el backend, paso 1
300380

301381
Cuando la aplicación se inicie, obtenga las anécdotas del backend implementado usando json-server.
302382

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

305385

306-
#### 6.14 Anécdotas y el backend, paso 2
386+
#### 6.15 Anécdotas y el backend, paso 2
307387

308388
Modificar la creación de nuevas anécdotas, de forma que las anécdotas se almacenen en el backend.
309389

0 commit comments

Comments
 (0)