logo

midulive


Transcribed podcasts: 605
Time transcribed: 13d 3h 7m 36s

This graph shows how many times the word ______ has been mentioned throughout the history of the program.

Bueno, pues vamos a aprender hoy SWR, que significa Stale While Revalidate, ¿vale?
Stale While Revalidate.
Stale While Revalidate es una cosa que es bastante antigua, era una estrategia de HTTP,
del protocolo HTTP, de hecho está aquí arriba que lo explican,
que al final lo que quería decir es, yo te doy lo que tengo cacheado,
mientras, por otro lado, voy a recuperar la última información y te la muestro cuando puedo.
Así que es una estrategia para que la experiencia del usuario sea mucho mejor
y de esta forma, pues tú le puedas mostrar al usuario rápidamente lo que tiene,
¿sabes? Tú le dices, oye, mira, esto es lo que tengo en la caché, toma,
y entonces la experiencia del usuario es buenísima, porque ve al principio lo que tengas en la caché,
mientras por detrás se está actualizando desde el servidor los datos, ¿vale?
Se están revalidando, por eso es Stale While Revalidate, ¿vale?
O sea, es como que estás atrás, estás atrasado mientras se revalida,
pero de esta forma tú siempre lo que tienes es que tienes información,
aunque sea vieja, y siempre la tienes en estado de actualizándose, actualizándose, ¿vale?
Hoy estoy hablando...
Es como el optimístico de React Query.
Es parecido a React Query, de hecho, tiene cosas que se le parecen mucho,
aunque vamos a ver que ese WR es, bueno, en mi opinión, más sencillo.
Puedes hacer también UIs optimistas, pero no funciona exactamente con...
O sea, es un poco manual eso que sea optimista, ¿vale?
No es que le pones un flag y ya está, de hecho, me imagino que lo iremos viendo y ya está.
Bueno, aquí vemos un uso bastante sencillo, importamos un hook, importante, es un hook de React,
y simplemente es uno, solo un hook.
Use SWR from SWR, ¿vale?
Aquí tendríamos un componente que es Function Profile,
y aquí, al utilizarlo, tendríamos que pasarle aquí...
Esto sería como la key, importante, la key, que esto es un tema interesante,
el tema de tener una llave para identificar lo que sería esta llamada que se hace,
porque esta key es importante.
Claro, tú lo ves y dices, pero si esta URL...
Esto es como la URL, ¿no?
Uy, voy a bajarle un poco la música, me parece que está muy fuerte.
Al menos yo me estoy quedando sordo.
Vale, pum.
Vale, pues esta key ya veremos cómo se utiliza con este Fetcher, cómo funciona,
porque aquí no hay ningún Fetch, ¿dónde está esta magia?
¿Qué está pasando?
Uy, tiene mi dedito.
Me parece bien.
Vale, pues este hook, como podemos ver, aquí pone que devuelve dos cosas,
pero devuelve más cosas, luego las veremos,
pero la más importante justamente es la información, o sea, tiene un error.
Si tiene un error, pues devolvemos, mostramos lo que queramos,
y si no tenemos la data, es que está en loading,
y finalmente, pues podemos mostrar con la data lo que sea.
Features, bueno, ahí, creo que está en castellano, por cierto.
Creo que está en castellano, mira, pum, ya en castellano.
Características, obtención de datos rápida, ligera y reutilizable.
Buah, me encanta.
Momento teletienda esto un poquito, ¿eh?
Caché integrada de duplicación de solicitudes, experiencia en tiempo real,
agnóstico al transporte, al transporte, me encanta.
Bueno, agnóstico al transporte y al protocolo,
esto quiere decir que esto debería funcionar con GraphQL, por ejemplo.
Cositas así, ¿vale?
Serversal rendering, incremental status regeneration, ¿vale?
TypeScript ready, React Native.
Y esto es todo lo que tendría.
Es que tiene cosas muy interesantes.
Por ejemplo, tienes navegación rápida, bueno, esto ya lo he comentado,
polling on interval, esto tú le puedes decir que cada 5, 10, 20 segundos,
pues vaya haciendo un fetching de datos.
Dependencia de los datos, esto no sé qué quiere decir.
Revalidation on focus, ¿vale?
Esto es lo que quiere decir, revalidation on focus, esto es muy interesante.
Esto es que tú te puedes ir de la pestaña, ¿no?
Tú abres otra pestaña, me voy aquí, y cuando vuelves a la pestaña,
se vuelve a revalidar los datos automáticamente, lo cual es bastante interesante.
Mutación local, bueno, esto es lo de UI optimista.
Lo que puedes hacer es mutar la caché antes incluso de hacer la mutación en el servidor,
lo cual es bastante potente.
Hacer un retry automático, paginación y scroll, bueno, y react suspense, y mucho más, mucho más.
Y encima todo esto, no es muy grande esta librería.
A ver, no, SWR.
Vamos a ver cuánto ocupa, pero ocupa 4Ks.
Es que casi no ocupa nada, o sea, es bastante chiquitita.
Bueno, pues vamos a ver dónde lo podemos utilizar en el advent.js, si os parece.
Vamos aquí al docs.
Yo ya os digo que lo vamos a poder utilizar en unos cuantos sitios, ya os lo digo yo.
Ya he instalado el paquete de...
Ah, no, no he instalado.
Juraría que lo he instalado, lo he instalado en otro sitio.
SWR, ¿vale?
Up to date, 767 milisegundos.
Yo entiendo que funcione así.
Vamos a ver dónde lo vamos a poder utilizar, ¿vale?
Mira, aquí yo creo que es un buen sitio.
Estos son los challenges, challenges.
Y en los challenges estos, veo que Tailwind por ahí, al final, ¿qué tal la experiencia?
Bueno, lo comenté ayer justamente y bien, bien.
Está bien, pero bueno, ya dije ayer que hay cosas que me gustan, otras que no tanto.
Y creo que lo malo es que si fuese un proyecto muy grande para mantener a largo plazo, sería un poco complicadito.
Mi dupana, ese soy yo, mi dupanita.
Mi dupana.
Qué chévere.
Ay, tú sí que eres arrecho.
Eso me encanta.
Arrechísimo.
Ah, esa es una buena palabra.
Arrechísimo.
Bueno, pues vamos a ver esta de challenges.
Index.
Vale.
Pues aquí, ¿ves?
Ah, mira, mira.
Este es perfecto.
Mira, mira, si ya me lo puse.
Me puse un comentario.
Usa SWR.
Ay, tú sí que eres arrecho, midu.
Que en el pasado ya te pusiste comentarios.
Muy bien, muy inteligente.
Vale, vamos a intentar importarlo.
No puse, creo que es, a ver, desde SWR.
Ahora no sé si es el default.
Sí, es el default.
SWR.
¿Es el default o no es el default?
Bueno, a ver.
Es el default.
Sí, el default.
Esto es una cosa interesante.
Muchas veces, vamos a hablar de esto.
Vamos a hablar de esto.
Y es que muchas veces hay gente que dice, debería utilizar el default, debería utilizar el nombrado y tal.
Hay mucha gente que está en contra del default.
A mí no me desagrada, pero bueno, sí que tiene sus casos de uso, lo reconozco.
Pero, en el tema del default, lo que sí que puede ser interesante es que el default lo que haga es lo que tiene que hacer por defecto el módulo.
En este caso, SWR, si te fijas, el default lo utiliza para esto.
Voy a asegurarme que utiliza el default.
No la vaya a liar, pero sí.
¿Ves? O sea, el módulo por defecto importa esto.
Claro, esto tiene sentido especialmente cuando se piensa en import dinámicos y cosas así, que tú lo que quieres decir es lo que importarías por defecto sin pedirle nada, cuál sería el módulo que tendría que importar.
O sea, conceptualmente tiene sentido, pero es verdad que, claro, como el nombre que tú le puedes poner aquí sea el que te dé la gana, al final puedes tener problemas de naming.
Aquí le puedo poner así, en otro sitio así, en otro sitio así, y eso es lo que sería un poco complicadete.
Pero, bueno, yo creo que puede tener sentido y especialmente en import dinámicos muchas veces sí que ayuda.
Vale, USSWR.
Bueno, pues aquí lo que vamos a hacer es tener aquí el data useSWR.
Ah, mira, madre mía, Guija Copilot.
Dios mío, que ya lo sabe.
Ya sé que arrecho significa otra cosa en Colombia, pero yo estoy utilizando el arrecho de Venezuela.
¿Vale? Además, sé que en Venezuela arrecho puede ser estar arrecho, puede estar enfadado o esto es arrechísimo, que puede ser como que es algo que está muy bien.
Vale, ya me dice aquí.
Vamos a pasar este API Challenge barra User.
Ah, porque este, vale, porque este es el del User.
Vale, vamos a ver si esto funciona.
API barra Challenges barra User.
Vale, me estoy acordando que ahora hay otros cambios que quería hacer, pero bueno, vamos a empezar con este.
Vale, y esto me debería dar en data, deberíamos tener los solve Challenges, ¿no?
Vale, de hecho aquí debería sacar los solve, o sea, esto debería ser data.solve.
Vale, data solve, data solve Challenges, solve Challenges.
Estoy mirando, claro, si no tengo usuario, ostras, esto puede ser un problema, ¿eh?
Esto puede ser un problema.
Esto puede ser un problema porque a lo mejor no sé si tengo el usuario de primeras.
Yo creo que sí que lo debo tener.
O sea, yo creo que el usuario no debería ser importante.
Porque este usuario, si no tengo usuario, pues intenta hacer esto y esto no debería ser ningún problema.
Vale, vamos a quitar todo esto y vamos a intentar a ver qué tiene esto.
Vale, el Fetcher hay que hacerlo, ¿eh?
El Fetcher ese no sale nada.
Por defecto no utiliza ni Fetch, ni Axios, ni nada.
Somos nosotros los que deberíamos decidir cómo lo utiliza.
Entonces, este Fetcher, que creo que está por aquí, mira, me lo voy a copiar porque voy a utilizar justamente Fetch,
lo podríamos tener aquí.
Esto es un método que al final aquí lo que recibiría serían todos los argumentos.
Con estos argumentos se los pasaría el Fetch y el Fetch haríamos el REST, lo transformamos en JSON y ya lo tendríamos.
Luego veremos si esto tiene sentido que lo hagamos así o lo hagamos de otra forma.
De hecho, lo que estoy viendo es que si yo le pasase esta URL, ¿cómo la estaba pasando?
Bueno, sí, que puede ser porque es relativa.
Claro, esto es lo bueno de NextDS, que como todo queda relativo, pues queda brutal.
Vamos a ver si esto funciona y luego nos preocuparemos de otro tipo de cosas.
Venga, localhost 3000, retos, vale, solve a change is not defined, eso está bien.
Vamos a ver si es la consola, me sale mi consola, vale, undefined, empezamos mal.
Empezamos mal.
Oye, ¿por qué me salía, por cierto?
Ah, claro, es que tengo aquí un montón de cambios porque estuve tocando el tema del dark mode.
Vamos a poner esto que es media, un momento.
Voy a refrescar esto, que si no, no me saldrá modo oscuro.
Uy, se me ha quedado pinchado.
Dame.
Ahora sí, refrescar.
Mira, internal error.
API barra challenges.
¿Por qué me está haciendo barra challenges?
Ah, no, no, no es que me está haciendo barra challenges, es que me está intentando aquí el solve challenges este que es normal, pero es que tampoco quiero que todavía vaya ahí.
Vamos a ver, data.solve, data.solve includes.
Y con esto, esto debería desaparecer.
Vale, pero me sale en define.
¿Por qué me sale en define?
Hostia, API barra challenges barra user.
Esto es porque cuando recupero el usuario, aquí en la API, challenge, el barra user, ¿cómo es?
Barra challenges.
Ah, es que está mal, ¿no?
He puesto mal la voz rel, creo que es así.
Challenge, ¿puede ser?
Sí.
Vale, pues ya está, arreglado.
Arreglado.
Hostia, está en modo...
Ah, y voy a quitar los cambios que tengo por aquí, porque tenía aquí unos cambios que estaba intentando hacer como para el modo oscuro.
Vamos a hacer un stash de todos estos cambios.
¿Esto qué es?
Vale, esto sí, esto también.
Hacemos un stash.
Y le vamos a poner modo oscuro con clases.
¿Vale?
Ah, digo, ¿por qué no es esa parte?
Vale, pues ya está, fuera.
Venga, refresco y vamos a ver esto, si funciona bien.
Vale, pues funciona bien, ¿vale?
Ahora sí que funciona bien.
Aquí podemos ver que primero me pone undefined y luego me pone solve y me aparecen.
Y de hecho, si refresco...
A ver...
Si refresco...
Bueno, sí que sigue dando un salto.
Yo pensaba que no daría un saltito, pero sí que lo da, ¿eh?
Sí que da el saltito.
Lo malo de esto es que ahora a ver cómo yo puedo ver que esto funciona exactamente.
Pensaba que a lo mejor el salto no lo daba.
Bueno, a ver, tiene sentido, ¿no?
Porque la primera vez que entras...
Pero fíjate que me he quitado el useUser, el useEffect, el useState, todo esto.
Y fíjate todo el código que me he quitado en un momento.
O sea, me he quitado el useEffect, me he quitado el fetch, me he quitado todo esto.
De hecho, vamos a hacer otra cosa.
Como esto lo voy a necesitar más de una vez, el useSwr este, que voy a ver todos los sitios donde hago un fetch, vamos a utilizar esto, ¿vale?
Vale, navUserProfile.
Bueno, esto no sé hasta qué punto esto tiene mucho sentido.
Porque esto es setLoadingTrue.
Esto sería como una mutación en todo caso.
Este lo vamos a dejar para el final.
Aquí tendríamos el este, a lo mejor sí que lo podemos simplificar.
Este tiene pinta de que lo vamos a poder simplificar.
¿Pero el caché es persistente o está en memoria?
La caché, me imagino que la podremos ver por algún lado.
Debería estar por algún sitio.
A ver si la encontramos.
AliSupports.
No sé, pero debería estar por aquí.
No sé si sería en memoria a lo mejor.
De hecho, si quitamos esto, vamos a ver si...
No, sí, sigue haciéndolo.
Pensaba que a lo mejor lo guardaría en local storage y ya está.
Pues va a ser en memoria, ¿eh?
No persiste cuando haces el refresh y todo esto.
Pensaba que sí que lo haría, ¿eh?
Lo cual sería ya increíble.
Y a lo mejor sí que hay alguna forma de hacerlo, que también sería interesante.
Mira, lo ves.
Caché.
Caché, create caché provider, new map.
Ya, pero el map está en memoria.
Access current caché provider, extend caché, ta, ta, ta.
Mira, local storage.
Based persistent cache.
Pues mira, lo puedes hacer en un persistent storage.
A lo mejor quieres hacer un sim de tu caché de local storage, no sé qué.
Como mejora, puedes utilizar memory caché como buffer y escribir en local storage periódicamente.
Hostia, qué buena idea.
Buah, sí, ya ves.
Madre mía, esto es un proyectazo, ¿eh?
Esto que comento aquí es un proyectazo.
Pero mira, esto es súper interesante.
Al final puedes hacer esto y entonces con esto se supone que sí que persistiría.
De hecho, vamos a intentarlo.
Como por ahora solo lo he utilizado aquí, por ahora debería ser bastante fácil.
A ver, tú, tú, tú, ¿cómo sería?
Vale.
Aquí parece que se puede hacer un componente que se llama swrconfig.
Como siempre va a ser igual en todo nuestro proyecto, lo vamos a utilizar en un sitio.
Aquí en app, pues aquí en app.
La verdad es que este app también lo debería simplificar.
Es que ves, en la app tengo demasiadas cosas aquí.
Tengo muchos componentes, tengo muchas historias aquí.
Voy a simplificarlo, ¿vale?
Voy a sacar el componente este del app, que lo tengo ahí en medio y a lo mejor no tiene tanto sentido.
Lo vamos a sacar fuera y que se haga un poco más legible.
Vamos a llamarle header, jsx, todo este app.
App, user, container, logo, es que es todo este container, ¿no?
Container, sí, todo este container sería el header, ¿vale?
Header, ta, ta, ta, ta, ta, ta, ta, ta, ¿vale?
El nap link, además lo puedo sacar de aquí también.
Todo esto también.
Mira, esto es lo bueno de utilizar, de no utilizar paces relativos, que ahora todo esto lo puedo cortar y pegar.
De hecho, voy a cortar también este.
Puedo cortarlo y pegar y funcionar desde el principio, ¿sabes?
Tú lo pones aquí, pam, y ya funciona.
Los imports ya funcionan.
En lugar de utilizar imports relativos, utilizas como un alias, que esto lo he enseñado en algunos vídeos, con este jsconfig, aquí.
Base URL, punto.
Y así puedes hacer que tus imports no sean todos relativos, ¿ves?
En lugar de hacer punto, punto, barra, punto, punto, barra, pues le dices, bueno, desde la raíz, components, barra, container.
Y ya está.
Y es mucho, mucho, mucho, mucho más fácil de trabajar.
Así, mucho más fácil.
Bueno, y te hace ir mucho más rápido.
Eso por descontado.
En este caso ya se nota.
Vale.
Y el nap link, que lo tengo aquí, este también me voy a traer.
Que esto, si no me equivoco, ya no lo necesitamos por aquí.
Y aquí sí que lo necesito porque es el subcomponente.
Vale.
Hay que importar el link de next link.
Y con esto, bueno, vamos mejorando poco a poco, vamos mejorando el código.
Vamos mejorando un poco el código.
¿Qué falta le hace?
Vamos a ver que esto siga funcionando.
Ahí, sí.
Si me voy a producción, seguro que funciona.
Solo faltaba.
Vale.
Veo que no porque no estoy utilizando el header.
Estaría bien utilizar el header, ¿no?
Estaría, sería interesante, desde luego.
Header, ahora sí.
Vamos a ver ahora.
Vale, ahora sí que aparece el header.
Perfecto.
Muy bien, muy bien.
Perfecto.
Bueno, no sé si eso, que no lo hemos comentado.
No sé si habéis visto el tercero ya.
¿Lo habéis visto o no?
Es en memoria, sí, sí, es en memoria.
Y aquí también se puede configurar, como React Query.
Se puede solucionar.
El report no es público.
No es público, no es público todavía.
Vamos a volver al tema este de SWR.
Ahora que he hecho esta pequeña refactorización, ¿vale?
Que me he quitado el header.
Ahora esto queda un poquito más fácil de leer.
Aunque esto también lo podría eliminar.
Venga, va.
Es que me lío.
Sé que me lío.
Pero es que necesito ir haciendo refactors porque si no, use analytics.
Es que si no, no terminamos nunca.
Es que si no, no me entero el código y al final me sale mal.
Vamos a hacer también un custom hook para quitar todo este tema de analíticas de la app, ¿vale?
Lo hacemos en un custom hook que quedará mucho mejor.
Así que export default, use analytics.
A ver, ¿cómo dice el use user?
¿Lo hice nombrado o lo hice default?
Nombrado, pues nombrado.
Lo importante, analytics.
Es que lo hagamos todo igual.
Si empezamos a hacer cada uno de una forma, mal asunto.
Vale, use effect, bla, bla, bla, use analytics.
Y esto en principio no devuelve nada.
O sea que ya está.
Vamos a quitar todo esto.
Ah, mira, podemos quitar el use router este, ¿no?
De hecho.
Oye, de hecho, ¿por qué no se queja de que el router no existe?
Qué peligro.
Qué peligro tiene mi linter.
A ver, vale, vamos a hacer aquí use analytics, que le importe.
Y el fathom, este, lo importamos aquí.
Bueno, también vamos a ir viendo cómo se refactorizan las cosas, que falta hace.
¿SWR tiene sentido en llamadas post?
También tiene llamadas.
No sé, ya verás que no, si hacemos alguna, no es tanto utilizarlo en llamadas post,
sino que tú puedas hacer la UI optimista en el sentido de que puedas actualizar la caché antes del post.
Y después del post puedas hacer un sync.
Eso sería un poco el asunto.
Vale, use analytics, vale, use router.
Mira, y es que nos hemos quitado aquí un montón de cosas.
Un montón de cosas.
Vale, router.
¿Qué falta?
La dependencia router events.
Bueno, espero que esta dependencia no nos fastidie el tema.
Vale, mucho mejor.
Ya la app.
Mucho mejor.
Vamos a ver.
Voy a ver que esté enviando el track.
Y a ver, ¿cómo se llama?
Va, no.
Fadzone, no.
Track, no.
Udir.
Este.
Waterboa, se llama.
Waterboa.
Manifest, no sé qué.
No vamos a retos.
Vale.
Bueno, tiene buena pinta.
Vale, ahora que hemos hecho todo esto, vamos a volver con SWR con el tema de la caché, ¿vale?
El tema de la caché que quería probar era lo del local storage, que tenía buena pinta, ¿vale?
Eso es lo que estamos haciendo.
De hecho, ahora lo estamos como configurando.
Utilizando este componente SWR config, podemos configurarle ciertas cosas sin necesidad de tener que hacerlo manualmente en todos los sitios que lo utilicemos.
Y eso es lo que quería hacer justamente aquí en MyApp.
Por eso lo estaba simplificando.
Para poder utilizar aquí el SWR config este, ¿vale?
Con esto tenemos que envolver nuestra aplicación y de esta forma todas las veces que utilicemos SWR dentro de nuestros componentes, ya irá con esa configuración por defecto, ¿vale?
SWR config from SWR, ¿vale?
Entonces, este provider de caché y tal, lo que vamos a hacer es utilizar el local storage este.
¿Vale?
Ahora lo voy a poner un poco mal.
Luego veremos aquí cómo tiene que funcionar.
Provider.
Y aquí ponemos local storage provider.
¿Vale?
Se supone que ahora sí que debería guardar en el local storage las llamadas y que por lo tanto, digo yo, no deberíamos ver un salto.
Vamos a ver.
¿Vale?
Local storage is not defined.
Empieza bien.
Ah, claro.
Claro, claro.
Es que esto funcionaría si no se ejecutase en el servidor.
Pero sí que se ejecuta en el servidor.
Entonces, a ver qué podemos hacer aquí.
Podemos hacer que si...
Bueno, joder, estaba pensando más o menos esto.
Bueno, no exactamente eso, pero...
Return map...
Claro, pero esto puede traer problemas, entiendo, ¿no?
Esto puede traer problemas.
Esto puede traer problemas porque yo me imagino...
Vamos a ver si cuela.
No, esto tiene que ser si es define.
Es un define.
Si no...
Uf.
Está haciendo...
Uy, como que casi, ¿sabes?
Porque esto...
Esto es tan rojo.
¿Por qué es tan rojo eso?
¿Sabes?
Es como que casi, pero no del todo.
Porque sí que se ha completado.
Qué raro eso, ¿no?
Pero, ¿ves?
El problema es que en servidor y en cliente no está renderizando lo mismo.
Si fuese totalmente en el cliente esto, entonces sí que tendría sentido.
Pero, claro, este app que ves aquí, esto se está ejecutando también en el servidor.
Y esto lo que está haciendo es que hay un mismatch.
Porque esto es súper interesante.
Porque lo que renderiza el servidor y el cliente no son lo mismo.
Entonces, si no es lo mismo, pues se cabrea.
De hecho, aquí se está quejando.
¿Ves?
Dice, esperaba que lo que había renderizado en el servidor fuese lo mismo que renderizabas en el cliente, básicamente.
Y al haber un mismatch se vuelve un poco loco y por eso vemos que la UI no está del todo bien.
Bueno, pues nada, vamos a olvidarnos del local storage por ahora.
Y lo vamos a dejar por ahora, vamos a dejarle esto vacío con un objeto vacío.
Voy a refrescar.
Entiendo que ahora sí que está bien, ¿vale?
Vale, vamos a ver otros fetch que podamos pasar.
Y lo que quiero hacer con lo del srconfig, vamos a ver un momento la srconfig.
Es que el fetcher que ya había hecho antes, ¿vale?
Yo había hecho este fetcher que había hecho y que se lo estaba pasando por aquí.
En lugar de tenerlo aquí a mano, como lo vamos a tener que volver a utilizar, o de hecho podríamos volver a utilizarlo y luego vemos cómo lo arreglamos esto, ¿vale?
Venga, vamos a ver dónde más podemos utilizar este fetch.
Vale, app challenges, response, await.
Este es el post.
Vale.
¿Esto qué es?
Esto es en el test.
Esto tampoco lo puedo hacer aquí.
Esto es con el login.
Y esto es otro post.
Y este, este sí que es un...
Vale, vamos a empezar con este.
Luego veremos si podemos empezar a hacer los otros.
Import, use swr, from swr.
Y ves, aquí tengo un loading, un user, set user, que el set user, bueno, el set user, cuidado porque lo paso fuera.
Claro, esto tendría que pasar un mutate.
Interesante con esto, ¿eh?
Ojo, cuidado.
Vale.
Aquí se puede complicar un poco más la cosa.
Tenemos que probar bien el tema del login para no romper nada porque el login puede ser dramático.
Dramático.
Hago lo del login y entonces en Twitter me cancelan directamente.
Vale, vamos a intentar utilizar con el data, creo que esto tiene un loading, vale, no me lo dice porque todavía no lo estoy utilizando, swr.
Y aquí vamos a poner que la key es happy user y aquí le vamos a pasar otra vez el fetcher.
El fetcher por ahora vamos a utilizar el mismo, pero luego veremos que esto se puede simplificar para no tener que hacerlo así todo el rato y pegarlo en todos los sitios que lo vamos a necesitar.
Y aparte de data, a ver, vamos a ver, tiene isValidating, isValidating, mutate y error, vale, o sea que si no tiene data básicamente es que está haciendo el loading.
Loading, si no tiene data, perdón.
Vale, loading, setLoading.
Es que, ¿qué es lo que hace el isValidating?
IsValidating, pero sí, pero quiero saber qué es lo que hace, es que no lo explican.
Creo que el isValidating no hace, comienza, a ver, isValidating, vale, gracias por la búsqueda, es muy útil, muy útil ha sido la búsqueda, me ha ayudado mucho, gracias, gracias búsqueda.
Gestión de errores, obtención de datos, ah, es que no existe en ningún sitio el isValidating, o sea que igual no sirve para nada.
Vale, bueno, por ahora vamos a dejar así.
User, setUser, claro, ¿cómo hacemos de utilizar el contexto?
¿Podríamos evitar utilizar el contexto?
¿Sabes? Podría cargarme el contexto, porque al final lo bueno que tiene ese wr también es que es global y allá donde lo pidas, donde pidas esta información al final la va a tener guardada.
A ver cómo es este context del user, mira, de hecho aquí lo he visto así.
Pues yo creo que esto, ojo, ojo, ojo que esto es muy interesante, que nos vamos a poder cargar a lo mejor, nos vamos a poder cargar el contexto de user.
Ojo, ojo, si nos lo podemos cargar, que va a ser muy interesante y vamos a ver todavía más la potencia de cómo puedes utilizar ese wr como un estado global.
Que de hecho ayer me estuve viendo un vídeo de, me estuve viendo un vídeo de Dan Abramov que hablaba justamente de que él ya no utilizaría Redux para nada.
Luego a mí la gente me cancela y luego el creador de Redux dice que a día de hoy no utilizaría Redux y entonces está bien.
Es que, vale, pues vamos a intentar hacer sin el user context, vale, user context fuera, esto fuera, yo entiendo que esto tendría un mutate, vale.
Y entonces te estabas preguntando, ya, claro, entonces Dan Abramov, ¿qué es lo que recomienda?
Recomienda dos cosas, una React Context API y por otro lado utilizar, pues, librerías como Apolo, como SWR, como React Query, vale, en el que al final lo que ocurre
es que la gestión de este tipo de datos es como una forma más declarativa y que no imperativa, sabes, que no tengas que estar ahí todo el rato como haciendo cosas.
Y aquí vamos a intentar hacerlo, a ver si nos sale, ¿vale? Vamos a intentar recuperar el usuario, si te fijas yo tenía este use effect que miraba si tenía el usuario, pues, fuera.
Si no, fetch, no sé qué, no sé cuánto del usuario y todo esto. Que la verdad es que no recuerdo esta lógica porque dice, si no, ah, si ya tiene el usuario entonces no hacen nada.
Claro que la verdad es que tiene sentido. De hecho el SWR este, si no me equivoco, también ahí tiene un conditional, sí, obtención de datos condicional, que igual también lo podríamos hacer.
Pero bueno, por ahora de eso nos vamos a olvidar. Y esto, ¿ves? Que hacía un set user, set loading, o sea, aquí tenía como diferente lógica, como para saber si tengo el usuario,
si estoy cargando el usuario, si no estoy cargando el usuario, sí. Un rollazo, un rollazo, como puedes ver.
Así que lo que vamos a intentar es cargarnos todo esto, todo esto. Vamos a utilizar, fíjate, todo lo que nos hemos cargado.
Y lo que vamos a hacer es recuperar el usuario. El mutate este debería ser el set user. Mira, este set loading, set loading.
¿Por qué será este? Es que este set loading seguramente no lo necesitamos. Vamos a ver dónde lo estamos utilizando.
Set loading true. Voy a comentarlo en aquellos sitios donde se esté utilizando porque me parece a mí que este set loading no lo vamos a necesitar más.
¿Sabes? No vamos a tener que hacer esto de una forma manual de llamar al set loading.
Vamos a poder hacer que esto sea como más automático. Me da la sensación.
Y este set loading... También fuera. Bueno, no, perdón. Este set loading no, que este set loading es de aquí, de este...
Ah, no, también, también, perdón. También es del usuario. Fuera, fuera. Fuera, fuera. Caca, caca.
Vale. Voy a guardar datos cambios.
Vale. Este set loading lo voy a dejar por ahí, pero no lo vamos a utilizar.
Set loading... Esto que no haga nada.
Set user. Vale. Set user.
Aquí lo que vamos a hacer es tema este del mutate.
¿Ves que aquí tenemos el mutate? Vamos a ver. Revalidar.
Puedes recuperar una función mutate de uses svroderle config hook and broadcast a revalidation message.
Ah, pero ¿por qué? No se puede hacer desde el...
Ah, yo pensaba que el mutate me lo devolvió aquí.
Sí, pues sí que devuelve aquí el mutate este.
Sí que lo devuelve.
Masándose los datos actuales.
Con mutate puedes pasar a una función asíncrona que recibirá el valor actual de AKH si lo hay y devolverá un updated document.
Datos devueltos por mutate.
Vale. Wait, mutate, update user. Eso es lo que quiero.
Justamente es lo que quiero.
Vale. O sea que yo creo que el mutate este debería ser como el set user.
Básicamente.
Así que vamos a poner...
Set user.
Mutate.
Luego veremos si esto funciona.
Loading, user.
Y el data este, esto debería ser data user.
Creo que esto devuelve el user o el data directamente es el user.
Hostia, buena pregunta, Midu.
Vamos a ver aquí el user.
¿Qué había hecho yo aquí?
Esto devolvía un objeto, ¿vale?
Con user.
O sea que esto debe ser data user.
Y el loading debería ser que si no tiene data...
Pues está loading.
Esto lo quitamos.
A ver.
Esto no va a funcionar de primera, lo sabe Dios, ¿vale?
O sea, esto no va a funcionar de primera porque si no ya sería de locos.
Pero lo que estamos haciendo...
Lo estabas usando como un loading global.
Sí.
Y yo creo que esto lo vamos a poder simplificar con SWR.
Ay.
Me pueden recomendar un Midu.
Pero de View.
Vidu.
Un Vidu.
Un Vidu.
Igual algún día le damos mucha caña.
Si yo no trabajase...
Estaría todo el día aprendiendo.
Y le daría mucha caña a View también.
Vale.
Entonces.
Voy a refrescar.
¡Oh!
No, a ver.
No, no puede ser.
Esto ha funcionado demasiado fácil.
Esto ha funcionado demasiado fácil.
A ver, a ver, a ver.
A ver, a ver.
Esto no puede ser.
Esto no puede ser.
No, puede ser.
No me lo creo.
No me lo creo.
¿Qué hemos hecho aquí?
Esto es demasiado fácil.
Eso ha sido demasiado fácil, ¿vale?
O sea, ha sido demasiado fácil.
O sea, yo entro.
Y cuando entro, ¿ves?
Se pone Loading hasta que sabes si tengo el usuario.
Y recuperar el usuario, ¿vale?
Entonces.
Veo que parece que funciona bien si ya estoy...
Si ya tengo el usuario.
Si ya tengo el usuario, parece que funciona bien.
Hasta ahí bien.
Pero, ¿ves?
Loading funciona bien.
O sea, es increíble.
Fijaos la de código que he quitado.
Y me he cargado...
No solo he quitado todo este código.
Es que me he cargado un contexto.
O sea, es increíble.
Es increíble.
Pero espérate porque ahora me falta lo difícil, ¿eh?
Me faltará lo difícil que será...
Si cierro sesión...
¿Ves?
Si cierro sesión, ahí debería aparecer un...
Ah, el Loading ha salido eventualmente.
¿Habéis visto que ha salido eventualmente?
A ver si refresco.
Vale.
Bueno, esto funciona bien.
El único problema ha sido que ha salido como demasiado tarde.
Oh, pero me ha gustado, ¿eh?
Me ha gustado.
Ya tenemos dos cosas funcionando.
O sea, bien.
Bien.
Me gusta.
Estoy contento.
Estoy contento.
Fíjate, ¿eh?
Me he quitado el Loading de aquí.
Aquí pone Handle Logout.
Handle Logout.
Y aquí dice Set Loading True.
Claro, esto lo hacía para...
Si le daba Logout...
Vale.
Esto es lo que podríamos hacer aquí.
Entiendo.
A ver.
Si tenemos...
Claro, yo es que tendría que forzar lo del Loading.
¿Y cómo forzo lo del Loading?
¿Sabes cómo visualmente forzo lo del Loading?
Es que no sé si tendría que ponerle otro estado y hacer lo mismo.
Porque, claro, es que aquí tengo que hacer un fetch al Magic User Logout, un fetch al API Logout, y entonces luego hago el Set User, que esto es para mutar justamente el usuario y quitarlo.
Que esto me lo ha hecho.
Me lo ha hecho porque he visto que ha desaparecido de aquí.
De hecho, sí, sí, de hecho no está.
Y si refresco, no aparece.
O sea, esto me lo ha hecho perfecto.
Esto me lo ha hecho perfecto.
Lo que me gustaría es que cuando le doy al Logout me aparezca que está cargando.
Y eso, claro, eso no es tan fácil.
Porque, bueno, podría poner el Set User al principio.
Claro.
Si pongo el Set User al principio, me debería hacer la mutación.
Debería perder los datos.
Vamos a probarlo.
Vamos a probarlo.
Esa también, esa la he pensado.
Que Kinga Ficus, muy bien, Kinga Ficus.
Esa también tiene buena pinta.
Vamos a probar.
Mira, y voy a probar si funciona el Login también.
Importante.
Vale, el Login funciona.
Estoy flipando, estoy alucinando de lo fácil que ha sido esto.
Estoy alucinando ahora mismo.
Porque ha sido increíblemente fácil.
Vale, le doy a cerrar sesión.
¡Ah!
¡Qué rollo!
Habéis visto, ¿no?
Que durante un momento lo ha hecho.
Pero luego...
Yo creo que...
Yo creo que esto lo ha roto.
Porque esto ha cambiado el usuario.
Ha vuelto a pedir el usuario.
No, o sea que esto...
Vale, vamos a probar esto que me habéis comentado.
SetUser...
Ah, qué lástima, ¿eh?
Porque está cerca.
Vale, decíais por aquí, es validating...
Entonces decía Kinga Ficus, me decía...
Is validating o...
Si está validating o no tiene datos.
Vamos a...
Sí, sí, ¿eh?
Kinga Ficus, increíble.
O sea, hemos sacado un contexto con dos líneas de código.
Es que es brutal, es increíble.
Me encanta.
Me encanta.
Vale, voy a asegurarme que esto está bien.
Iniciar sesión está bien.
Vale.
Le damos a iniciar sesión.
Va a Magic Link.
Iniciar sesión.
Vale.
Oleo, a ver.
Midu, no consigo que me acepte la consola de ejercicio 3 y el local me va perfecto.
Esa es la frase, arco.
Esa es la frase.
En mi local me funciona.
Pues, a ver, pásamela en Discord y la probamos.
Venga, a ver, cerra.
No, tampoco, ¿eh?
Bueno, tarda menos.
Ha tardado menos.
Pero veis que hay como un...
A ver, creo que igual ahora también funciona un poco así, ¿eh?
No pasa nada.
Pero solo funciona en mi...
A mí me cuesta mucho hacer autenticación.
Bueno, tarda un poco, pero...
Hostia, ¿qué ha pasado ahí?
Ah, ¿sabes lo que ha pasado ahí?
Claro.
Eso es...
Oh, qué interesante.
Mira, os voy a enseñar una cosa que es muy interesante.
Os voy a enseñar una cosa que es muy chula.
Si yo ahora inicio sesión aquí,
¿vale?
Voy a iniciar sesión en esta pestaña, ¿vale?
Fíjate que tengo dos pestañas abiertas.
Esto es lo mejor.
Esto es lo mejor que tiene.
Esto es lo mejor que tiene SWR.
He iniciado sesión aquí, ¿vale?
He iniciado sesión en esta pestaña.
Si ahora me vuelvo a esta pestaña
donde no tenía la sesión iniciada...
¡Oh!
¡Qué chulo!
¡Qué chulo!
¿Habéis visto esto?
Se ha sincronizado solo.
Voy a cerrar ahora la sesión aquí.
¿Vale?
En esta no tengo la sesión...
He cerrado la sesión.
En la otra pestaña la tenía abierta.
Fíjate.
¡Qué chulo!
¡Qué chulo!
No me diréis que no es increíble.
Es la bomba.
Es la bomba.
O sea, no solo me he cargado un montón de líneas de código,
sino que además...
Sino que además hemos conseguido sincronización entre pestañas.
De gratis.
O sea, brutal.
Uriberna.
Uriberma.
Hola, Miguel.
Tiempo sin estar por aquí.
Saludos.
Sigue así.
Un abrazo, hombre.
Se te echaba de menos.
¿Qué magia haces?
Bueno, lo que hemos hecho, básicamente,
es sincronizar el estado entre pestañas.
O sea, no solo tenemos un estado global,
porque eso te lo puede dar Redux fácilmente, ¿no?
Muchas, ah, Redux, pam, estado global.
Vale.
Pero es que no solo tenemos, en este caso, un estado global,
sino que lo que hemos conseguido...
Lo que pasa, lo malo que veo es que de vez en cuando hace como un polling.
Claro, cuando cambias de pestaña,
si tú vas cambiando de pestaña cada dos por tres,
pues, eventualmente hace esto como que está cargando,
porque está recuperando para ver si realmente sigue en el mismo estado en el que estaba antes.
Bueno, pues no solo hemos conseguido un estado global,
sino que hemos conseguido también que se sincronice entre pestañas.
A mí eso no me gusta.
No puedes tener dos tabs abiertos.
¿Qué dices?
Pero sí, es súper típico.
Yo, por ejemplo, en Twitter,
tengo 80.000 millones de tabs abiertos muchas veces.
Y entonces, imagínate que estas notificaciones que te salen aquí,
pues, tiene sentido.
Por ejemplo, mira, para que veas que es bastante común.
Si yo ahora le doy aquí, ¿vale?
Pum.
Y yo vuelvo aquí, ¿ves?
Se ha sincronizado.
Tiene bastante sentido.
Tener dos usuarios diferentes entre pestañas,
o sea, en un mismo navegador, no tiene mucho sentido.
Porque al final, además, puedes tener problemas de integridad.
¿Por qué?
Porque la sesión que tendrías en las cookies solo puede ser la de un usuario.
O sea, aunque tú visualmente vieras que aquí pone mi dudez,
si yo voy a otra pestaña y resulta que no tengo la sesión iniciada,
tendrías problemas.
O sea, no puedes tener la sesión iniciada de dos usuarios en una misma sesión de un navegador.
No puedes.
No puedes porque las cookies colisionarían.
Entonces, aunque tú visualmente vieras que estás con un usuario,
en realidad no estarías.
Tendrías que abrir una instancia diferente, ya sea con incógnito y tal.
O sea que tiene todo el sentido del mundo que haga esto, ¿eh?
Todo el sentido del mundo.
Yo manejaría el loading con un estado local y listo.
También es una buena idea.
Mira, te acabo de pasar ejercicio 3 en el Discord.
A ver, retos.
Voy a iniciar sesión.
Importante.
Pero está muy chulo.
O sea, a mí me gusta mucho, ¿eh?
Mira, te vas a retos.
Fíjate.
Fíjate.
Esta es otra, ¿eh?
Mira, fíjate en esta, que esta también está muy buena.
Si voy a retos, aquí está en verde.
Y en la segunda pestaña que no había iniciado sesión todavía,
ahora está en verde también.
Es genial.
O sea, es que es genial.
O sea, es genial.
Me parece brutal.
Además, quitando todo código,
porque el use context este que tenía, tenía un contexto aquí.
¿Dónde está el contexto?
Este contexto a tomar por saco.
A tomar por saco.
Y nos vamos a la .js.
Y todo este contexto fuera.
Ya no tengo contexto.
Tengo un tablo local.
Es increíble.
Es increíble.
Fijaos el código que he quitado.
Mira, me he cargado, me he cargado todo este código.
Y aquí, fijaos cómo lo he dejado.
Me he cargado todo esto.
Y sin un state, sin un efecto, sin nada.
Sin nada.
Bueno, y de hecho, este fetcher lo puedo quitar, ¿eh?
También.
Este fetcher ya sobra.
Ah, no.
No, espérate, que todavía esto no os lo he explicado.
No os lo he explicado.
No os lo he explicado.
Amigos, tranquilos.
Que no os lo he explicado.
Mirad.
Justamente para evitar estos fetchers que tengo por aquí más de uno.
¿Veis que tengo dos?
Porque, claro, siempre que utiliza este fetcher.
Lo que podemos hacer aquí en SWRConfig,
o SW o W, según de donde seas,
pues aquí podríamos utilizar fetcher, ¿vale?
Y aquí utilizar una sola vez el fetcher,
que al final sí que lo puedes sobreescribir si lo necesitases.
Pero en lugar de poner esto, es que encima queda todavía más limpio, amigos.
Más limpio.
Más limpio y sale reluciente.
Mira.
Es que me parece tan bonito.
Y ahora aquí lo que podemos hacer es,
tenemos aquí el fetcher y nada,
le decimos que utilice este fetcher por defecto.
Y creo que esto funciona igual.
Refresco.
¿Vale?
El fetcher por defecto.
¿Vale?
Es normal que tal.
Ahora aquí cierro la sesión.
¡Qué rabia el loading este que no hace nada!
¡Hostia!
Cuando me ha cerrado la sesión me ha ido a...
Ah, sí.
Porque hago un router.push a la home.
Es normal.
Ahora, si vuelvo aquí,
voy a ver que la sesión se ha cerrado.
Esto sí, pero esto no.
Esto se me ha quedado aquí completado.
¿Por qué?
Porque no está haciendo una revalidación de los datos.
A ver si refresco deberían desaparecer.
Ahí ha fallado el tema.
Ahí ha fallado.
¿Por qué será eso?
Habrá que mutarlos.
¿Sabes?
Habrá que forzar la mutación.
Lo podría hacer.
Podría forzar la mutación.
Lo podemos mirar.
Vale.
Pero lo importante al menos es que ahora ya estamos utilizando el fetcher.
Queda mucho más limpio.
Lo tenemos en un solo sitio.
Y así, donde utilizamos ese WR, solo le tenemos que indicar la key.
Esta key es la que se le pasa al fetcher que tendríamos aquí, justamente.
Perdón.
¿Dónde la tenemos?
Aquí.
En app.
¿Vale?
A este fetcher le llegaría aquí, en arcs.
Esto sería A, B, C.
O sea, esto sería la URL, las options.
No me acuerdo si son options o header o como se le llame.
Aquí llegaría todo lo que se le pasase.
Y el primero que se le pasa es la key.
Que la key, por suerte, es justamente la URL.
¿Vale?
La URL es el primer parámetro.
Así que, por eso funciona exactamente igual que si al fetcher le pasara es todo.
Y nada, la respuesta la transformamos a JSON y ya lo tendríamos.
Y con esto hemos simplificado el código un montón.
Un montón.
Nos hemos quitado ahí un montón de efectos y de historias.
¿Vale?
¿Qué más?
¿Qué más tendríamos por aquí?
Porque el user este, a ver, lo estamos utilizando en unos cuantos sitios.
El setLoading este, ¿ves?
Es que no lo estamos utilizando.
Es el loading.
Esto, claro, este es el loading.
¿Esto qué es?
El loginButton.
Claro, es que aquí esto ya no tiene sentido.
Es que ni siquiera esto, ¡buah!
Mira, la de código me voy a poder quitar.
Esto fuera.
Venga, siguiente.
UserLoading.
Vale, este sí que tiene sentido.
Porque este es el que hace la diferenciación entre qué tiene que renderizar.
Pero bueno, ha quedado bastante bonito.
Le vamos a quitar encima todo esto.
Ah, no.
Esto sí que solo tengo que dejar.
Bueno, esto a mí, yo prefiero, cuando tengo que hacer esto,
es no utilizar nunca relativos.
Yo prefiero siempre utilizar...
Cuando tienes esto configurado, de que funciona con unos paths
que son a partir del current working directory,
prefiero utilizarlo siempre y olvidarme del relativo.
¿Por qué?
Porque si muevo mis componentes o lo que sea, siempre funcionan.
Lo cual a mí me encanta.
Vale.
Este sea el useUser, el profile, ¿vale?
UseUser, setUser.
Y esto sería para hacer el quitarlo y ya está.
UseUser, ¿vale?
Así que esto fuera.
Test.
UseUser.
¿Por qué el test?
Vale.
Hostia, este es importante.
Vamos a probar que este funcione.
Nos vamos a retos, nos vamos a contando ovejas.
Completa el reto.
Vale.
Si yo ahora cierro la sesión...
Tarda un ratillo, ¿eh?
Hostia, este se queda tonto, ¿eh?
Ves que este...
Ese completado no se arregla, ¿eh?
Tendría que...
Ahora veré por qué no se arregla.
Pero está claro que es un tema de la caché
que seguramente tendríamos que hacer un mutate.
Ahora te enseñaré cómo lo hacemos.
Vale.
Pues, vale.
Aquí tengo que iniciar sesión para registrar tus regresos.
Si voy aquí al reto...
¿Ves?
Pues me va a pasar lo mismo.
Inicia sesión para registrar tu progreso.
Vale.
Hasta aquí, bien.
Hasta aquí, bien.
A ver.
Inicio sesión.
Este se me va a activar de golpe.
Vamos a verlo.
Que es importante estos temas.
¿Recomiendas la autenticación directa de Firebase?
Sí.
Firebase está bastante bien para autenticar.
Ah, mira.
¿Ves?
Es que qué guay.
Qué chulo.
Ahora, pues ha funcionado perfectamente
y ya lo tenemos.
Vale, vale.
Y ya puedo seguir utilizando.
¡Ey!
¿Qué ha pasado ahí?
Ha pasado algo raro ahí.
No sé qué ha pasado, pero...
¿El diseño con qué lo hiciste?
Está hecho con Tailwind.
Está hecho con Tailwind.
¿Qué quería hacer?
Ah, sí.
Quería arreglar cuando haces lo de cerrar sesión.
Lo que está pasando aquí,
y así podemos hacerlo del mutate este,
es que cuando cerramos sesión...
Mira, voy a cerrar todo esto que tengo por aquí.
Pa, pa, pa, pa.
Cuando hacemos el logout...
No.
Cuando hacemos el logout...
Joder.
Logout.
Login button no.
Totalmente con logout.
Vamos a ver.
Aquí.
Nav user profile.
Vale.
Aquí podemos importar un import mutate
from SWR.
¿Esto se importa así?
Use SWR config.
Brokers a revalidation message.
Vale, vale.
¿Es desde use?
Vale, vale.
O sea, esto no es un mutate.
Pensaba que se podía importar el mutate este,
porque existir existe.
Entonces, ¿por qué existe este mutate?
O sea, que sí que se puede utilizar.
Yo creo que sí que se puede utilizar sin este.
Es que aquí dice que lo tenemos que importar de SWR config,
pero aquí parece que se puede traer el mutate directamente de SWR.
Yo creo que sí que se puede hacer.
Entonces, el mutate.
Vale.
Yo lo que creo que se puede hacer aquí cuando hacemos el logout y todo esto,
es que podríamos hacer un mutate y al mutate le podríamos decir la API.
Es que el setUser este hace justamente esto.
Entonces, en el challenges tenemos aquí una key.
¿Vale?
Esta key de API challenges user, esto, lo que podríamos hacer para evitar el problema que teníamos,
es utilizar esta key y decirle, esta key, pásale como data el null.
Y should revalidate, yo entiendo que sería false.
El revalidate sería como, esto sería mutar la caché, lo que tenemos en memoria,
la información que tenemos en memoria, de esta key, le pasaríamos date como data,
perdona, date, no, como data le pondríamos null y en lugar de revalidar,
que no tiene sentido revalidarlo, le pondríamos false.
Revalidate lo que haría sería un get, pero yo creo que no es necesario.
De esta forma aquí lo que podríamos poner, por ejemplo, sería clear,
mira, clear user data regarding completed challenges.
¿Vale?
Esto es lo que estaría haciendo.
Entonces, aparte de cerrar la sesión de usuario,
lo que estaríamos haciendo es limpiar la caché que tiene esta key,
no la revalidamos en el servidor y además,
lo que tenemos que hacer aquí es pasarle el null.
Y para asegurarnos, para el mutate este,
lo que vamos a hacer efectivamente es,
it works only as it only, no, it works only on my machine.
Bueno, le voy a quitar el only porque me gusta,
ah, sí, coño, es que le he puesto only y no ponía only.
¿Vale?
Pues vamos a hacer un mutate con it works only my machine.
¿Vale?
Guardamos los cambios y ahora, si cierro la sesión,
lo que debería haber es que los retos,
si te acuerdas antes lo que nos estaba pasando antes,
o si te estás entrando ahora,
lo que nos estaba pasando antes es que esto se quedaba en verde
porque no se estaba limpiando la caché cuando cerraba la sesión.
Entonces, voy a cerrar la sesión y esto debería,
de repente, pasar a rojo.
¿Vale?
Vamos a ver si funciona.
Bueno, voy a refrescar por si acaso.
¿Vale?
Venga, está todo en verde.
Voy a cerrar la sesión.
Me falta lo del loading.
¡Ay!
Bueno, vale, no pasa nada.
Es que tengo un push que me lleva...
Pero, ¿ves?
Está todo en rojo.
De hecho, podríamos quitar el push este.
No tiene mucho sentido el push.
Porque ahora que tengo esto mejor...
Es que, ¿por qué hacía el push?
El push lo hacía porque la UI quedaba mal.
Porque había cosas de la UI que se veían mal.
Pero con esto, que ahora va a quedar bien,
creo que tiene sentido.
Alejandro y dice, ¿cuál es el motivo del renombrado?
El motivo del renombrado es que muchas veces lo que pasa
es que la gente puede pagar con MiduCoins
el tema de nombrar variables y funciones.
Y como ha pagado Jelliter, ha pagado, pues lo hemos hecho.
Y, bueno, ya que lo hemos hecho, lo vamos a quitar ya
para que quede claro que es un mutate.
No es que sea necesario cambiar el nombre de las variables.
Pero, bueno, ha sido divertido el nombre.
Me ha gustado, me ha gustado.
Vale, por ejemplo...
Ah, claro.
Y ahora cuando entre aquí...
Claro, esto también es interesante.
Porque si inicio sesión aquí...
Cuando inicio sesión aquí...
Vale, ahora esto debería, de repente,
ponerse en verde, eventualmente.
Vale, aquí yo inicio sesión en esta pestaña
y en la otra pestaña se debería poner todo en verde.
Buah, increíble.
Me encanta.
Me encanta.
No, permanente no.
¿Permanente cómo me vamos a poner?
Lo hemos hecho un momento.
Creía que tenía colisión con otra librería.
¿Te imaginas?
Bueno, hay una colisión con otra librería.
Voy a poner...
Solo funciona en mi máquina como método.
Vale.
Oye, qué bien.
Es que me gusta mucho lo que hemos hecho aquí.
Os he enseñado el mutate,
que tiene todo el sentido del mundo.
Me encanta, ¿eh?
Me encanta.
Me encanta.
¿Cómo haces los despliegues de la web?
¿A dónde lo mandas con el Continuous Integration?
¿Sería súper un vídeo o algo para aprender?
Bueno, Félix, en realidad,
lo que tengo es un repositorio
que se llama AdventGS, creo.
¿A secas?
Creo que sí.
Es privado, ¿vale?
O sea, todavía no lo he abierto.
De hecho, es que tengo que arreglarme muchas cosas.
Y esto lo que está integrado con Vercel.
Cada vez que hago un...
Aquí están mis cómics de mierda
para que os ríais un día.
Add more test.
Lo que tengo por aquí
es que cuando se hace el deployment,
o sea, cuando tú haces un cómic,
pues se deploia con Vercel.
Y nada, en un minuto lo tenemos en producción.
Un minuto y medio.
Impresionante.
¿No va al comando del Discord?
¿Cuál?
No sé cuál es.
¿Habías dicho por qué no usas TypeScript?
Sí que uso TypeScript de vez en cuando.
Pero bueno, a ver,
esto era un proyecto que era muy rápido
y lo quería hacer inmediatamente, ¿sabes?
O sea, no quería liarme con TypeScript.
Un problema,
una cosa que no me gusta mucho de TypeScript,
que bueno, está en mi opinión,
es el hecho de que el...
O sea, al final salva tiempo,
pero es al final, no al principio.
Puede salvar tiempo al final.
Y una cosa en la que no salva tiempo
es básicamente en los tiempos de build,
que a mí no me gusta...
O sea,
el tema es que si quieres utilizar bien TypeScript,
te la puedes liar un poco, parda.
Estoy súper...
Es que os puedo jurar que estoy contentísimo.
Es que no puedo creer que hayamos quitado
tantas líneas de código
utilizando algo tan sencillo en un momento.
Vale, a ver qué más tenemos por aquí de fetch.
Entiendo que el logout este no tiene mucho sentido.
Lo que este set user...
Claro, si yo le pongo este set user antes...
Claro, es que pone null.
Coño, si me lo pone null...
A ver, eso es una cosa que no entiendo muy bien.
Porque data...
Si no tiene...
Si no tiene data...
Está cargando.
¿Y qué data puede ser que esté ahí?
Eliazarn.
Gracias, hombre, por suscribirte durante un mes.
Claro, si por ejemplo el usuario...
A ver, voy a mirar un momento esto,
que tengo curiosidad de ver esto bien.
Si el usuario...
Yo cierro sesión.
Lo de cerrar sesión...
Lo de cerrar sesión...
Me gustaría que fuese como más...
Cierro el usuario.
User null.
Data.
Claro, porque tiene el user.
Entonces, una cosa es que tenga el user a null...
Vale, vale, ahora lo he entendido.
Una cosa es que tenga el user a null...
Y otra cosa es que no tenga data.
Por lo tanto...
Claro, si yo le pongo el set user a null...
Aquí...
En realidad le estoy poniendo el user a null...
No le estoy poniendo el data a null...
Vale, ese es el tema.
Ese es el tema.
Entonces...
Claro, lo que tendría...
Podría hacer dos cosas, básicamente.
Podría hacer...
Tener otro estado por aquí...
Y el set loading, por ejemplo...
Tener otro estado y ya está.
Que fuese más visual.
Claro, porque es que hay que diferenciar...
Que esté el user pero a null...
O que esté...
Set user...
Claro, mutate.
Y esto muta la data.
Eso es lo que pasa, vale.
Gente, estaba pensando...
Perdónate.
¿Ya hicieron el tercer reto?
Sí, lo hemos estado comentando por aquí.
Claro, ahí está Jeriter.
Es que estaría el...
¿Cómo está gestionando la sesión?
¡Buah!
¿Se me puede explicar eso ahora?
Para activar el modo oscuro...
Tendrías que cambiarlo en las preferencias del sistema.
Todavía no está...
No hay un botón.
Y si haces un mutate de API user a null...
Es que eso, Blackmore, es justamente lo que...
Este mutate...
Este mutate que te devuelve el useSWR...
Hace justamente eso.
Y si te fijas este set user...
Hago este mutate.
Entonces estoy haciendo justamente esto.
De poner el mutate a null.
Lo malo es que eso lo que me está haciendo es esto.
Es pasarme el data user a null.
No me está...
¿Sabes?
Me está mutando la data que ya tengo.
Por...
O sea, claro.
No puedo...
No puedo como...
Como...
Como decirle...
No, no.
Que no tienes data.
No.
Data ya tienes siempre.
¿Sabes?
Lo que pasa es que puede ser que esté más actualizado o menos actualizado.
Y ya está.
Ese es el tema.
Bueno.
No pasa nada.
Lo que podría hacer es justamente esto.
Tener aquí un loading.
Y...
Y ya está.
Me pregunto...
Una cosa que me pregunto...
Me estoy preguntando...
Me estoy preguntando una cosa.
No sé si esto será posible.
No lo he mirado.
Pero tengo curiosidad.
O sea...
Yo podría hacer esto.
O sea...
Yo podría decirle...
Loading.
¿Sabes?
Podría generar un estado global.
Vamos a probarlo.
Vamos a probarlo.
Entiendo que aquí estaría el fetch.
Pero...
Yo aquí lo que voy a hacer...
En lugar de hacer...
Eh...
Sé que es muy pirata esto.
Eh...
Sé que es muy pirata.
¿Sabes?
O sea...
¿Se podría hacer esto?
Eh...
¿Se podría hacer esto?
¿Qué pensáis?
Es muy pirata.
Pero...
Da muchas ganas.
¿Eh?
De...
De tener el loading con esta...
¿Sabes?
Con esto que se sincroniza por todas las pestañas y tal.
Entonces podríamos tener este...
Eh...
Podríamos tener este loading...
¿Por qué le pones tipos al JavaScript?
No le estoy poniendo tipos.
Esto no es un tipo.
Esto es el...
Renombrar la key data por loading.
Eso es lo que estamos haciendo.
Entonces en lugar...
Podríamos poner...
O loading...
O no tengo data...
O estoy cargando.
O sea...
O estoy cargando...
O no tengo data.
Eso sería el tema.
Bueno, que sería lo mismo, ¿no?
Uno u otro.
Algo así.
Eh...
Isvalidating ya lo quitaría.
Este mutate loading...
Que esto devolvería true...
Pero esto lo devolvería la primera vez.
Que total no es interesante.
Y si dejas el isvalidating solo...
Es que el isvalidating...
Aparte de que no me aparece aquí...
Cosa que me da bastante...
¿Sabes?
Que no aparece en la documentación.
Isloading si no tiene error y no tiene data.
Ah, bueno.
Esto tiene sentido.
Si no tiene error y no tiene...
Si hay una request o revalidation loading.
Claro, es que...
A lo mejor no quiero que exista una revalidación.
Revalidación.
¿Sabes?
Es lo que dice Sergio aquí.
Dice...
Cargar solo pasa una vez.
Que es cuando o no tienes data...
O hay un error.
Claro.
Pero la validación pasa más de una vez.
La validación lo que significa...
Es que estás intentando revalidar los datos...
Que tienes en ese mismo momento.
Y es diferente al isloading.
Claro.
Para hacer el isvalidating...
Lo que tendría que hacer es que cuando hago el logout...
Y es que aquí no tiene sentido.
Porque cuando hago el logout...
Logout.
Cuando hago este logout...
Lo que tendría que hacer es como llamar a...
O sea, tendría que hacer el fetch de este API logout.
Tendría que hacer este.
Y que a la vez también mutase el del user.
¿Sabes?
Y entonces estaría cargando.
Estaría haciendo una revalidación.
Pero es que creo que no tiene mucho sentido.
O sea, estaría mejor hacer este.
Y que esto pasase además...
Aquí.
Lo ideal sería...
Claro.
Pero en lugar de setUser este...
SetUser sería aquí.
Y aquí sería el setLoading.
SetLoading...
Y esto ponerlo a true.
Y el setLoading aquí ponerlo a false.
Sé que no es tan guay.
¿Vale?
No es tan guay.
O bueno...
El setUser este podría llamar internamente a setLoading.
Que también podría ser una idea.
El setUser...
Que tiene este mutate.
Podríamos hacer aquí.
SetUser.
UseCallback.
Y aquí le podríamos poner esto.
Y aquí podríamos poner mutate.
Aquí tendríamos user.
Y aquí tendríamos user.
SetLoading false.
Y bueno.
Podríamos pasar en mutate.
Y ya está.
Esto es una cosa que podríamos hacer.
Para simplificar todo el tema del setUser.
Y en todos los sitios que se van a llamar el setUser.
Ya se pone set...
Esto se pone a false.
Y ya está.
A ver.
Es una idea bastante brutal.
O sea...
Sería interesante.
No es setLoading.
Es mutateLoading.
Bueno.
Es verdad.
Pero en este caso.
Es porque si no tendría que empezar a cambiar todos los usos.
Por un lado tendría que cambiar todos los usos.
Y por otro lado.
Una cosa que justamente intento con un custom hook.
Es no mostrar el tema de...
No mostrar las entrañas de lo que hace el custom hook.
Por ejemplo.
Una cosa que veo mucho.
Que a mí no me gusta mucho.
Que hace la gente.
Es el hecho de decir fetch.
O set no sé qué.
A ver.
SetUser tampoco me gusta mucho.
Tampoco me gusta mucho.
Porque parece que es el setState.
No choca un poco que un setUser mute la probloading.
Bueno.
Eso es una cosa que queda interna de aquí.
Del setUser.
Al final cuando seteas el usuario.
Pues terminarías el loading.
Lo bueno que haces esto.
Es que esto te lo evitas hacer fuera.
A ver.
Que tampoco lo hemos probado.
Que igual todo esto que hemos hecho no funciona para nada.
Vamos a probarlo.
De hecho.
Este está petando.
Use callback is not defined.
Bueno.
Use callback is not defined.
Use callback is not defined.
Vamos a ver.
¿Cómo que es not defined?
Si ahora sí que lo estoy usando aquí.
Ay no.
Que no importa donde no es.
Jeje.
Perdón.
Esto es aquí.
Import.
Bueno.
Vamos a probarlo.
Si funciona bien.
Y no.
Lo dejaremos como estaba.
¿Ves?
De hecho.
Ahora esto.
Se ha quedado aquí.
Picueto.
Y esto.
Se ha quedado picueto.
Porque.
Aquí tenemos siempre.
Que el use user.
Esto empieza con un loading.
A true.
Ahora empieza a empezar.
False.
Vale.
Tendríamos iniciar sesión.
Le daríamos.
Iniciar sesión.
Vamos a ver.
Ah.
No es el loading.
En la línea 10.
Me refiero.
Línea 10.
Ay.
Tienes razón.
Esto es multi-loading.
Vale.
Vale.
Tenías toda la razón.
Tenías toda la razón.
Gracias por avisar.
Pues así.
Imposible que funcionase.
Así.
Sí que era imposible que funcionase.
Así que.
Venga.
Va.
Casi que no termino el tercer reto.
Como dijo Amido ayer.
Funciona.
Pero no estoy orgulloso.
No, no.
La frase es.
Estoy contento pero no orgulloso.
Estoy contento pero no orgulloso.
Esa es la frase.
Set loading.
Nos pone que.
Que eran define.
A ver.
Esto en handle logout.
Es que esto es una.
Una locura que tengo aquí.
Que no tengo el linter.
Y es un rollo.
Set loading.
App.
User profile.
No.
Pero ahora sí que está aquí.
Set loading.
Use user.
Set loading.
Ahora sí que lo tengo.
O sea.
No me engañes.
No me engañes.
Set loading.
Ah.
It's not a function.
Dice que este set loading.
Este mutate loading.
No es.
Ay.
Es que esto.
Es así.
Vale.
Ahora sí.
Vale.
Pues veis que ahora sí que lo hemos hecho.
Habéis visto.
Ha quedado bien ¿no?
Ahora sí que ha quedado bien.
Ha quedado fino.
Ha quedado finito.
Mira aquí.
Incluso podría hacerlo aquí también.
Bueno.
Bueno.
Esto me ha gustado.
Ha quedado bastante bien creo.
Ha quedado bien.
Bueno.
Aquí podría ponerle también el loading.
Pero ha quedado bien.
Ahora sí.
Le doy aquí.
Y le doy a cerrar sesión.
Mira.
Uy.
Me ha dejado fatal.
Me ha dejado fatal.
Qué cabrón.
Qué cabrón.
Pero si había salido bien.
Si hace un momento lo ha hecho bien.
¿Por qué?
Hostia.
Mira.
Esta aplicación está haciendo demasiadas peticiones.
Pobrecitos.
Pobrecitos.
Están flipando conmigo.
Oye.
Pero la primera vez había quedado tan bien.
Que me lo había creído y todo.
Me lo había creído y todo.
Me lo había creído y todo.
Me lo había creído y todo amigos.
Me lo había creído.
Digo.
Ostras.
Que bien ha quedado.
Que no sé qué.
Mentira todo.
Mentira.
Use effect.
Authenticate.
User.
Get redirect.
Vale.
Esto vamos a poner aquí.
Un set loading.
A true.
A ver.
Vamos a ver.
Esto había quedado bien.
Hostia.
Pues ahora no lo hace.
Pero.
Me lo he imaginado yo.
O de verdad lo habéis visto que había salido bien.
Porque salía bien, ¿no?
Me siento engañado.
Pero la primera vez ha salido súper bien.
Y luego.
¿Por qué?
Bueno.
Pues nada.
Damos el.
Lo damos por perdido eso.
Sí, ¿verdad?
Salía.
Me sentí emocionado.
Yo también me sentí súper emocionado durante un momento.
Y al final.
Es que la verdad es que es una idea interesante.
El hecho de tener el loading ahí.
Creo que en SWR.
Creo que hay un use user también por aquí.
Mira.
Is loading.
Ah, mira.
Importante lo del error.
Igual eso sería interesante a mí.
¿Vale?
Is loading si no tiene error y no tiene data.
Si no tiene error y no tiene data.
Bueno, claro.
Es que el error me lo estaba saltando.
Me lo estaba saltando igualmente.
Bueno.
Set user.
Pam, pam, pam.
Vamos a dejarlo como estaba.
Y ya está.
Mutate.
Este es el loading fuera.
User.
Data user.
¿Vale?
Is error.
Bueno.
Is loading.
Is error.
Error.
¿Vale?
Welcome back.
Obtener datos.
Bueno, esto es como se haría, ¿no?
Use user.
Is loading.
Lo más bonito es que solo se enviará una request.
Esto también es interesante que no os lo he comentado y está muy chulo.
Y es el hecho de que aunque tú hagas esta petición desde cinco sitios diferentes, por ejemplo, lo que va a pasar es que se va a hacer solo una petición y va a sincronizar todas las peticiones dentro de tu página.
O sea, que eso es bastante potente.
Vale.
Voy a quitar todos los set loadings que he puesto.
Y al final, mira, me fío del is loading este.
¿Qué le vamos a hacer?
Si está bien, bien.
Y si no está bien, pues...
Pues, ¿qué le vamos a hacer?
Set loading.
Según esto no tengo ningún sitio.
Set loading.
¿Vale?
Y el loading...
Y ya lo dejo así y nos olvidamos del tema por ahora.
Y vamos a pasar a otra cosa que quiero hacer.
Vale.
Este sería is loading.
Si está cargando, tal.
Ta, ta, ta.
Is loading, loading, set state loading.
A ver, vamos a buscar todos los...
Vale.
Solo hay un sitio donde se enseña el is loading, que es arriba.
Vale.
Vale.
Pues, por ahora, vamos a dejarlo así.
Que así funciona.
Es verdad que no sale en el momento, pero no pasa nada.
¿Vale?
No pasa nada.
¿Qué le vamos a hacer?