Skip to content

Commit c6db68e

Browse files
authored
Merge pull request #2677 from Juanescacha/source
[es] Part8d content update
2 parents 4aae11f + 2744cc9 commit c6db68e

File tree

1 file changed

+50
-45
lines changed

1 file changed

+50
-45
lines changed

src/content/8/es/part8d.md

Lines changed: 50 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ La interfaz de nuestra aplicación muestra el directorio telefónico muy bien co
1111

1212
### Inicio de sesión de usuario
1313

14-
<!-- Lisätään sovelluksen tilaan muuttuja _token_, joka tallettaa tokenin siinä vaiheessa kun käyttäjä en kirjautunut. Jos _token_ ei ole määritelty, näytetään kirjautumisesta huolehtiva komponentti <i> LoginForm </i>, joka saa parametriksi virheenkäsittelijän sekä funktion _setToken_: -->
1514
Agreguemos la variable _token_ al estado de la aplicación. Contendrá el token del usuario cuando se inicie sesión. Si _token_ no está definido, representamos el componente <i>LoginForm</i> responsable del inicio de sesión del usuario. El componente recibe un controlador de errores y la función _setToken_ como parámetros:
1615

1716
```js
@@ -140,54 +139,68 @@ const App = () => {
140139
}
141140
// highlight-end
142141

142+
// highlight-start
143+
if (!token) {
144+
return (
145+
<>
146+
<Notify errorMessage={errorMessage} />
147+
<LoginForm setToken={setToken} setError={notify} />
148+
</>
149+
)
150+
}
151+
// highlight-end
152+
153+
return (
154+
<>
155+
<Notify errorMessage={errorMessage} />
156+
<button onClick={logout}>logout</button> // highlight-line
157+
<Persons persons={result.data.allPersons} />
158+
<PersonForm setError={notify} />
159+
<PhoneForm setError={notify} />
160+
</>
161+
)
143162
}
144163
```
145164

146-
El código actual de la aplicación se puede encontrar en [Github](https://github.com/fullstack-hy2020/graphql-phonebook-frontend/tree/part8-6), rama <i>part8-6</i>.
147-
148165
### Agregar un token a un encabezado
149166

150167
Después de que el backend cambie, la creación de nuevas personas requiere que se envíe un token de usuario válido con la solicitud. Para enviar el token, tenemos que cambiar un poco la forma en que definimos el objeto _ApolloClient_ en <i>index.js</i>.
151168

152169
```js
153-
import { setContext } from 'apollo-link-context' // highlight-line
170+
import { ApolloClient, InMemoryCache, ApolloProvider, createHttpLink } from '@apollo/client' // highlight-line
171+
import { setContext } from '@apollo/client/link/context' // highlight-line
154172

155173
// highlight-start
156174
const authLink = setContext((_, { headers }) => {
157175
const token = localStorage.getItem('phonenumbers-user-token')
158176
return {
159177
headers: {
160178
...headers,
161-
authorization: token ? `bearer ${token}` : null,
179+
authorization: token ? `Bearer ${token}` : null,
162180
}
163181
}
164182
})
165183
// highlight-end
166184

167-
const httpLink = new HttpLink({ uri: 'http://localhost:4000' }) // highlight-line
185+
const httpLink = createHttpLink({
186+
uri: 'http://localhost:4000',
187+
})
168188

169189
const client = new ApolloClient({
170190
cache: new InMemoryCache(),
171191
link: authLink.concat(httpLink) // highlight-line
172192
})
173193
```
174194

175-
<!-- _client_-olion muodostamisen yhteydessä oleva toinen parametri _link_ määrittelee, miten apollo on yhteydessä palvelimeen. Nyt normaalia [httpLink] (https://www.apollographql.com/docs/link/links/http.htm) -yhteyttä muokataan siten, että, että pyyntöjen mukaan [asetetaan headerille] (https://www.apollographql.com / docs / react / networking / authentication / # header) <i> autorización </i> arvoksi localStoragessa mahdollisesti oleva token. -->
176-
El parámetro de enlace dado al objeto _client_ define cómo apollo se conecta al servidor. Aquí, la conexión normal de [httpLink](https://www.apollographql.com/docs/link/links/http.htm) se modifica para que el [encabezado](https://www.apollographql.com/docs/react/networking/authentication/#header) <i>authorization</i> contenga el token si se ha guardado uno en localStorage.
177-
178-
<!-- Asennetaan vielä muutoksen tarvitsema kirjasto -->
179-
También necesitamos instalar la librería requerida por esta modificación
195+
El campo _uri_ que fue usado anteriormente para crear el objeto _client_ se ha reemplazado por el campo _link_, que define en un caso más complicado cómo Apollo está conectado al servidor. La url del servidor ahora está envuelta usando la función [createHttpLink](https://www.apollographql.com/docs/link/links/http.htm) en un objeto httpLink adecuado. El enlace se modifica por el [context](https://www.apollographql.com/docs/react/api/link/apollo-link-context/#overview) definido por el objeto authLink para que un posible token en localStorage se [establezca en el encabezado](https://www.apollographql.com/docs/react/networking/authentication/#header) <i>authorization</i> para cada solicitud al servidor.
180196

181-
```bash
182-
npm install apollo-link-context
183-
```
184-
La creación de nuevas personas y el cambio de números funciona nuevamente. Sin embargo, queda un problema pendiente. Si intentamos agregar una persona sin un número de teléfono, no es posible.
197+
Crear nuevas personas y cambiar números funcionan de nuevo. Sin embargo, hay un problema restante. Si intentamos agregar una persona sin un número de teléfono, no es posible.
185198

186-
![](../../images/8/25e.png)
199+
![browser showing person validation failed](../../images/8/25e.png)
187200

188-
La validación falla, porque el frontend envía una cadena vacía como el valor de _phone_.
201+
La validación falla porque el frontend envía una cadena vacía como valor de _phone_.
189202

190-
Cambiemos la función creando nuevas personas para que establezca _phone_ en nulo si el usuario no ha dado un valor.
203+
Cambiemos la función que crea nuevas personas para que establezca _phone_ en _undefined_ si el usuario no ha dado un valor.
191204

192205
```js
193206
const PersonForm = ({ setError }) => {
@@ -197,7 +210,7 @@ const PersonForm = ({ setError }) => {
197210
createPerson({
198211
variables: {
199212
name, street, city, // highlight-line
200-
phone: phone.length > 0 ? phone : null // highlight-line
213+
phone: phone.length > 0 ? phone : undefined // highlight-line
201214
}
202215
})
203216

@@ -208,20 +221,22 @@ const PersonForm = ({ setError }) => {
208221
}
209222
```
210223

211-
El código de aplicación actual se puede encontrar en [Github](https://github.com/fullstack-hy2020/graphql-phonebook-frontend/tree/part8-7), rama <i>part8-7</i>.
224+
El código actual de la aplicación se puede encontrar en [Github](https://github.com/fullstack-hy2020/graphql-phonebook-frontend/tree/part8-6), rama <i>part8-6</i>.
212225

213226
### Actualizando caché, revisado
214227

215228
Tenemos que [actualizar](/es​​/part8/react*and_graph_ql#update-the-cache) el caché del cliente Apollo al crear nuevas personas. Podemos actualizarlo usando la opción _refetchQueries_ de la mutación para definir que la consulta <em>ALL_PERSONS</em> se realiza nuevamente.
216229

217-
```js
230+
```js
218231
const PersonForm = ({ setError }) => {
219232
// ...
220233

221234
const [ createPerson ] = useMutation(CREATE_PERSON, {
222235
refetchQueries: [ {query: ALL_PERSONS} ], // highlight-line
223236
onError: (error) => {
224-
setError(error.graphQLErrors[0].message)
237+
const errors = error.graphQLErrors[0].extensions.error.errors
238+
const messages = Object.values(errors).map(e => e.message).join('\n')
239+
setError(messages)
225240
}
226241
})
227242
```
@@ -230,7 +245,7 @@ Este enfoque es bastante bueno, el inconveniente es que la consulta siempre se v
230245
231246
Es posible optimizar la solución gestionando la actualización de la caché nosotros mismos. Esto se hace definiendo una llamada de devolución de [actualización](https://www.apollographql.com/docs/react/api/react/hooks/#options) adecuada para la mutación, que Apollo ejecuta después la mutación:
232247
233-
```js
248+
```js
234249
const PersonForm = ({ setError }) => {
235250
// ...
236251

@@ -239,16 +254,13 @@ const PersonForm = ({ setError }) => {
239254
setError(error.graphQLErrors[0].message)
240255
},
241256
// highlight-start
242-
update: (store, response) => {
243-
const dataInStore = store.readQuery({ query: ALL_PERSONS })
244-
store.writeQuery({
245-
query: ALL_PERSONS,
246-
data: {
247-
...dataInStore,
248-
allPersons: [ ...dataInStore.allPersons, response.data.addPerson ]
257+
update: (cache, response) => {
258+
cache.updateQuery({ query: ALL_PERSONS }, ({ allPersons }) => {
259+
return {
260+
allPersons: allPersons.concat(response.data.addPerson),
249261
}
250262
})
251-
}
263+
},
252264
// highlight-end
253265
})
254266

@@ -258,11 +270,10 @@ const PersonForm = ({ setError }) => {
258270
259271
La función de devolución de llamada recibe una referencia al caché y los datos devueltos por la mutación como parámetros. Por ejemplo, en nuestro caso sería la persona creada.
260272
261-
El código lee el estado en caché de la consulta <em>ALL_PERSONS</em> usando [readQuery](https://www.apollographql.com/docs/react/caching/cache-interaction/#readquery) y actualiza el caché con la función [writeQuery](https://www.apollographql.com/docs/react/caching/cache-interaction/#writequery-and-writefragment) agregando la nueva persona a los datos almacenados en caché.
273+
query <em>ALL\_PERSONS</em> in cache by adding the new person to the cached data.
262274
263-
Tenga en cuenta que readQuery arrojará un error si su caché no contiene todos los datos necesarios para cumplir con la consulta especificada. Esto se puede resolver usando un bloque try-catch.
275+
Usando la función [updateQuery](https://www.apollographql.com/docs/react/caching/cache-interaction/#using-updatequery-and-updatefragment) el código actualiza la consulta <em>ALL\_PERSONS</em> en caché agregando la nueva persona a los datos en caché.
264276
265-
<!-- En myös olemassa tilanteita, joissa ainoa järkevä tapa saada välimuisti pidettyä ajantasaisena en _update_-callbackillä tehtävä päivitys. -->
266277
En algunas situaciones, la única forma sensata de mantener el caché actualizado es usando la devolución de llamada _update_.
267278
268279
Cuando sea necesario, es posible deshabilitar el caché para toda la aplicación o [consultas únicas](https://www.apollographql.com/docs/react/api/react/hooks/#options) configurando el campo que administra el uso del caché , [fetchPolicy](https://www.apollographql.com/docs/react/data/queries/#configuring-fetch-logic) como <em>sin caché</em>.
@@ -271,13 +282,13 @@ Sea diligente con el caché. Los datos antiguos en la caché pueden causar error
271282
272283
> <i>Solo hay dos cosas difíciles en Ciencias de la Computación: invalidación de caché y nombrar cosas. </i> Leer más [aquí](https://www.google.com/search?q=two+hard+things+in+Computer+Science&oq=two+hard+things+in+Computer+Science).
273284
274-
El código actual de la aplicación se puede encontrar en [Github](https://github.com/fullstack-hy2020/graphql-phonebook-frontend/tree/part8-8), rama <i>part8-8</i>.
285+
El código actual de la aplicación se puede encontrar en [Github](https://github.com/fullstack-hy2020/graphql-phonebook-frontend/tree/part8-8), rama <i>part8-7</i>.
275286
276287
</div>
277288
278289
<div class="tasks">
279290
280-
### Ejercicios 8.17.-8.22.
291+
### Ejercicios 8.17.-8.22
281292
282293
#### 8.17 Listado de libros
283294
@@ -317,20 +328,14 @@ Implemente una vista que muestre todos los libros según el género favorito del
317328
318329
#### 8.21 libros por género con GraphQL
319330
320-
En el ejercicio anterior 8.20, el filtrado podría haberse hecho usando solo React. Para completar este ejercicio, debe filtrar los libros en la página de recomendaciones mediante una consulta GraphQL al servidor. La consulta creada en el ejercicio 8.5 podría ser útil aquí.
331+
En los dos ejercicios anteriores, el filtrado se podría haber hecho usando solo React.
332+
Para completar este ejercicio, debe volver a realizar el filtrado de los libros según un género seleccionado (que se realizó en el ejercicio 8.19) usando una consulta GraphQL al servidor. Si ya lo hizo, no tiene que hacer nada.
321333
322334
Este y los siguientes ejercicios son bastante **desafiantes** como debería ser a esta altura del curso. Es posible que desee completar primero los más fáciles en la [siguiente parte](/es/part8/fragments_and_subscriptions).
323335
324-
Algunos consejos
325-
326-
- En lugar de usar <i>useQuery</i>, probablemente sea mejor hacer las consultas con el hook <i>useLazyQuery</i>
327-
- A veces es útil guardar los resultados de una consulta GraphQL en el estado de un componente.
328-
- Tenga en cuenta que puede realizar consultas GraphQL en un hook <i>useEffect</i>.
329-
- El [segundo parámetro](https://reactjs.org/docs/hooks-reference.html#conditionally-firing-an-effect) de un hook <i>useEffect</i> puede resultar útil dependiendo de su enfoque.
330-
331336
#### 8.22 Caché actualizado y recomendaciones de libros
332337
333-
Si recuperas las recomendaciones de libros con GraphQL, asegúrate de alguna manera de que la vista de libros se mantenga actualizada. Entonces, cuando se agrega un libro nuevo, la vista de libros se actualiza **al menos** cuando se presiona un botón de selección de género.
338+
Si ya realizó el ejercicio anterior, es decir, buscar los libros en un género con GraphQL, asegúrese de alguna manera de que la vista de libros se mantenga actualizada. Por lo tanto, cuando se agrega un nuevo libro, la vista de libros se actualiza **al menos** cuando se presiona un botón de selección de género.
334339
335340
<i>Cuando no se realiza la selección de un nuevo género, no es necesario actualizar la vista.</i>
336341

0 commit comments

Comments
 (0)