This graph shows how many times the word ______ has been mentioned throughout the history of the program.
Vale. Entonces, ahora lo que vamos a hacer es, tenemos dos opciones aquí. Lo que podemos hacer, o lo que te pueden pedir, es utilizar un custom hook. Todavía no sabéis lo que son los custom hooks, estamos haciendo un curso de React todas las semanas, los miércoles, aquí a las 6, y nos quedamos en el useState y el useEffect.
Pero ya solo con estos dos hooks que tiene React, ya te puedo comentar un nuevo concepto que es súper importante, que es súper potente, que es súper clave, y que como junior también tienes que dominar, porque es bastante básico.
Y es el tema, el concepto de los custom hooks, o hooks personalizados, ganchos personalizados. Y es que React te permite crear tus propios ganchos. Puedes crear, extraer parte de la lógica que estés haciendo con hooks,
la puedes extraer y le puedes poner el nombre que tú quieras. Y vas a ver que es súper fácil, súper sencillo, y que te va a simplificar muchísimo el código que vas a hacer.
Esto, en una prueba técnica de Junior Trainees, seguramente puede ser que te lo pidan, y si no te lo piden, te van a ver con muy buenos ojos si lo haces. Así que, quédate, entérate bien, que es muy fácil.
Mira, imaginemos aquí que tenemos el recuperar... Ah, mira, ostras, antes de contarte el custom hook, os voy a explicar otra que es bastante importante, porque hay otra cosa que os piden mucho.
Vamos primero con el de añadir el botón, que se me había olvidado. A ver, hay otra cosa que os suelen pedir un montón, que es añadir un botón. Ahora os explico lo del custom hook, que además nos va a venir bien, y además vais a ver un problemilla que vamos a tener.
Siempre os van a pedir que añadáis un botón, ¿vale? ¿Un botón para qué? Pues un botón para que refresquéis los cambios, para que refresquéis tanto esto, o que se refresque esto, y también la imagen, cosas así.
Entonces, imaginad que pone get new fact, por ejemplo. Porque lo que quieren ver es que sabéis reutilizar la lógica, ya sea con un servicio, con lo que sea, o al menos en el mismo archivo.
Fijaos que al principio, lo mejor que podéis hacer es poneros siempre en el mismo archivo. No os pongáis a crear un montón de componentes que os va a costar un montón.
Entonces, vamos a hacer primero esto, para ver cómo lo haríamos. Haremos aquí un handle click, y ahora es que esto nos va a ser interesante justamente para el tema del custom hook también.
¿Veis aquí que para recuperar la cita lo tenemos aquí en el use effect? Pues esto lo podríamos sacar, lo podríamos copiar aquí, en handle click, ¿no?
Y esto lo podríamos poner aquí, y con esto, pues, get new fact, le debería dar, me trae un nuevo fact, y se cambia la imagen automáticamente.
En este caso, se cambia la imagen automáticamente gracias a que hemos hecho lo del efecto. Igual cuando hacéis el botón, y teníais la solución anterior, no funcionaba como esperabais,
y ahí vais a tener un montón de problemas. Así que mejor que aquí, ¿veis? Ha funcionado automáticamente gracias a eso.
Obviamente aquí estamos repitiendo código. Aquí, ojo con esto. Lo primero que podéis hacer es simplemente, pues, decir, bueno, voy a sacar esto,
y ponerlo aquí, ¿no? Get random fact. Esto es lo primero que vais a querer hacer, y es normal, ¿eh? Esto está bien, no hay ningún problema,
lo hacéis así, ¿vale? Podéis ponerlo aquí dentro, esto lo podéis hacer como queráis. Podéis hacerlo así, o podéis pasarle directamente como acepta una función,
os puede quedar así, os va a quedar muy limpio, y además así le podéis explicar, oye, mira, es que sé que como es una función,
y esto me funciona, pues lo voy a hacer así. Y esto, pues, aquí lo mismo, este handle click,
podríais pasarle get random fact directamente, o lo podéis poner así, lo que prefiráis. Esto está bien, o sea, esto no pasa nada,
esto sigue funcionando, esto es correcto, tenéis una función, que tenéis get random fact y tal. Esto es un buen momento,
realmente es un buen momento para que realmente podáis separar un poquito de lógica, y luego, con los custom hooks,
llevarlo a otro nivel. ¿Por qué? Porque así lo que podéis decir es, vale, este get random fact, en lugar de dejarlo aquí,
vamos a empezar a hacer algo, ¿no? Vamos a decir, oye, voy a empezar a separar esto. Y fíjate que en lugar
de empezar a separar componentes, lo que vamos a empezar a separar en realidad es la lógica. Así que va a ser
bastante interesante de que la gente vea, ¿no? Que dice, ah, bueno, qué bien que lo estás separando. Y además lo vas a
separar bien, no lo vas a separar mal, como normalmente se hace, que se separa mal. Y vas a ver por qué.
Vas a ver por qué. Mira, si tú pones aquí los servicios. Midu, ¿estas pruebas se pueden presentar como TDD y el reto es elaborar
y pasar los test? A ver, estas pruebas normalmente son live coding. Si hacéis un live coding, yo os recomiendo
que no hayas TDD. Porque vais a tardar bastante más, la verdad, por desgracia. Pero si es una prueba
que es para, o sea, que os llevéis a casa, la podéis hacer con TDD y ya está, perfecto. Bueno, entonces, servicios.
Aquí vamos a hacer, por ejemplo, fax.js. ¿Cuál es la mala práctica que aquí hace todo el mundo a la hora
de extraer lógica de un componente de React? Y esto lo he visto así de veces, así de veces. Y está mal, ¿vale?
Y te lo van a preguntar y te van a pillar y te va a costar. Vale. Lo que hace la gente es esto. Dice, ah, voy a extraer
esto. Export. Vale, perfecto. ¿Qué es lo que necesito aquí? El cat endpoint. Vale, perfecto. Me lo traigo
aquí. Perfecto. ¿Y qué es lo que necesito aquí? El setfax. Vale, pues aquí, setfax. Vale, ya está.
Venga, perfecto. Get random, ¿no? Ahora quitamos esto. Esto lo tenemos que cambiar, ¿no? Vale.
Y aquí le pasamos el setfax, ¿no? Setfax. Setfax, ¿no? Get random fact. Esto lo vamos a importar.
Del archivo que hemos creado, que es random fact de services. Y esto mismo lo hacemos aquí.
Esto está mal. No hagáis esto, ¿vale? A ver, no es por nada. No pasa nada. Normalmente
a un trainee se le puede perdonar. A un junior realmente no se le debería perdonar. Esto
funcionar funciona, ¿vale? Esto funcionar funciona. Esto funcionar funciona. Pero te van a decir,
te van a decir, oye, entonces esto, esto lo vas a poder utilizar en otro sitio. Es buena
práctica, me doy. Lo hacen los seniors. No solo lo hacen. A ver, es que siempre decimos,
no, buena práctica lo hacen los seniors. Un junior puede tener dos años de experiencia. Dos
años de experiencia. Esto es importante. Por eso digo, un trainee que tiene cero, yo lo entiendo
que esto se le puede dejar pasar. A un junior con dos años de experiencia que diga que ha
trabajado con React y que al menos te separa la lógica. A ver, aquí lo que tenéis que
hacer... Sí, yo esto lo he visto a seniors también. Por eso digo, no es tanto que sea
senior, junior y tal. Yo lo que os digo, yo lo que os digo es que lo mejor que podéis
hacer es evitar siempre pasar el setState hacia afuera, ¿no? El setState es una cosa interna
del componente. Se lo dejáis ahí, ¿vale? Lo dejáis ahí quietecito. Aquí no le pasamos
el setFact. No necesita, el getRandomFact no necesita nada para funcionar. Lo que vamos
a hacer aquí es un return del setFetch, ¿vale? Nos aseguramos de hacer el return del
fetch. Esto es otro error muy típico. Y lo que hacemos aquí es devolver el fact.
Es lo que hacemos. Lo podéis hacer también con sinkAwait si queréis, ¿vale? Lo podéis
hacer así, lo podéis hacer como queráis. O así, o así. ¿Habéis visto como he transformado
a sinkAwait súper rápido? Ha flipado, ¿eh? Bueno, os voy a explicar el truco. Si queréis
pasar una función a sinkAwait súper rápido, aquí veis que tenéis tres puntitos, pues
le dais aquí comando punto y aquí tenéis convertir a sinkFunction. Y os la convierten
a sinkFunction en un momento, ¿vale? Y ya lo tenéis. Esto es un truco mágico que en
una prueba técnica os salva la vida, ¿eh? Por lo que lo queréis hacer. Entonces, ahora
este método sí que es realmente reutilizable. Ahora sí que es realmente reutilizable, ¿vale?
Y este getRandomFact lo podéis utilizar en Vue, en React, donde sea. Y aquí lo que vais a
necesitar, en realidad, es decir, oye, pues vamos a hacer que esto sea síncrono y aquí
hacemos el await y aquí tendríamos el newFact y hago el setFact, ¿no? Ahora sí. Aquí sí
que puedes hacer esto. O esto, esta lógica incluso la puedes extraer en un método si
quieres. Pero lo importante y lo interesante de esto es que ahora la parte de React que está
en React, la parte que no tiene nada que ver con React, no está en React, ¿no? Y esto
pues lo puedes hacer con el den si quieres. SetFact, por ejemplo. Y ya está. Estas serían
las dos formas de hacerlo, ¿vale? Algo me he cargado porque el getRandomFact... Ah, que
no he guardado los cambios. ¿Vale? Pues ya está. Con esto ya lo tendríais. Pero si vais
a separar la lógica de negocio en algún sitio, lo hacéis aquí, ¿vale? Con el getRandomFact
que no tenga la dependencia de React. No hagáis esto, ¿vale? Porque al final aquí además
os van a preguntar, os van a preguntar, ¿por qué le pasa la dependencia de setFact?
No. ¿Se te ocurre hacerlo de otra forma? O sea, te lo van a decir, ¿vale? Te lo van
a decir. Vale. Ahora sí. Ahora ya tenemos un botón que cada vez que cambia el fact, cambia
también la imagen, ¿no? Lo hace como un poquito uno detrás de otro. Bebe algo que se te
va a pegar los labios. Venga, va. Bebo. Bebo. ¿Explica los dos retuns? ¿Los dos retuns?
Antes de transformar a Sinkawait. ¿Este? A ver. Esto... Esto... A ver. Voy a copiármelo.
Voy a copiarmelo y lo explico. A ver. El fetch... Este fetch, ¿qué devuelve? Una promesa.
¿Cómo se resuelven las promesas? Con await, como hacemos aquí, o con el then. Entonces...
Entonces decimos, vale, then. ¿Qué devuelve el res.json? Pues lo que devuelve es una promesa.
¿Cómo se resuelve una promesa? Con el then. Pues concatenamos, ¿no? Estamos encadenando
porque al final las promesas... Tú haces promise.resolve2, ¿vale? Then... Aquí tendríamos
el número 2. El número 2. Si tú haces el return number, esto ya que devuelve. Esto siempre
devuelve una promesa. Con el número 2. Entonces puedes hacer otra vez un then. Las promesas
se pueden concatenar siempre. Porque una vez que devuelves una, todo lo que viene por detrás
también es una promesa. Ya sea con then si resuelve o con catch si tienes un reject. Pero
las promesas funcionan así. En este caso es que el res.json devuelve una promise. Por
eso tienes que hacer aquí una wait también. Punto. Ya está. ¿Cómo es que funciona el
then setfac? ¿Cómo es que funciona esto? Esto porque el setfac recibe el parámetro
del nuevo valor. Esto es lo mismo que escribir esto. Es lo mismo. Esto es súper importante
que lo entendáis porque esto significa que sabéis que podéis pasar las funciones como
parámetro. Esto es lo mismo. Es lo mismo. No es exactamente lo mismo porque aquí creas
una función, una función más y aquí le estarías pasando todos los parámetros. Esto
a veces es mala práctica. Lo vamos a dejar así, que es mejor práctica para que lo entendáis
bien. Hay que tener un archivo donde estén todos los endpoints a usar o tener el endpoint
una constante como lo tenéis. Yo empezaría primero con esto. Yo empezaría primero usando
esto y luego poco a poco. Vamos iterando. Vamos empezando. Ahora, por ejemplo, vamos a
ver cómo crear un custom hook y luego ya veremos cómo tener otro tipo de cosas. Pero por ahora
lo vamos a tener así. Lo que sí que está bien en este caso, al menos, es que hemos separado
la llamada al servicio. Tenemos aquí el endpoint. Y esto mismo lo podríamos hacer con este
del fetch. No lo voy a hacer porque es repetitivo, pero os animo a que lo hagáis. Ahora lo que
sí que vendría sería el tema de los custom hooks para reutilizar lógica de nuestros componentes.
Y esto es súper importante y súper, súper, vamos, esto es increíblemente importante.
¿Por qué? Porque vais a hacer que vuestros componentes y además seguramente os lo piden,
puede ser que os lo pidan o puede ser que directamente os digan, ¿no se te ocurre una forma
de reutilizar? Y si esto tuvieras que reutilizar en otro sitio, bueno, un custom hook es simplemente
reutilizar lógica de nuestros componentes en diferentes componentes y para eso lo tenemos
que extraer. ¿Cómo lo extraemos? Mira, vamos a extraer, por ejemplo, vamos a extraer el de la
imagen, ¿vale? Vamos a extraer toda esta lógica de la imagen. Porque esta lógica que tenemos aquí
normalmente es como muy complicada, ¿no? Tener este useEffect y si en otro componente quiero utilizar
esta lógica, ¿qué hago? ¿La copio y la pego? No. Vamos a crear un custom hook. ¿Cómo se crean
los custom hooks? Los custom hooks tenemos que crear una función que empiece con la palabra
use, ¿vale? Tiene que ser use porque lo utiliza React para saber que nos estamos refiriendo
a un custom hook. Y le vamos a dar un nombre. En este caso, pues sería para recuperar la imagen
del gatillo, ¿no? Bueno, pues vamos a hacer que se llame useCatImage. Esta es nuestra función.
UseCatImage. Aquí simplemente podemos devolver lo que queramos. Podríamos hacer un return y
devolver lo que queramos. Por ejemplo, esto. Y aquí ya podemos llamar este custom hook tan
fácil como esto. ¿Qué es lo que devuelve esto? Pues aquí devuelve el prefijo de la URL.
Ya está. Con esto ya lo tendríamos, ¿no? Esto sería un custom hook. Pero obviamente no queremos
que nos devuelva una cadena de texto y ya está. Lo que queremos es que haga la lógica
que necesitamos. ¿Cuál es la lógica que necesitamos? Vale. La lógica que necesitamos
para recuperar la imagen del gato es, por un lado, el estado. Así que el estado lo cortamos
y lo ponemos dentro del custom hook. Y por otro lado, el efecto. Este efecto que teníamos
por aquí. Así que lo cortamos y lo vamos a pegar aquí dentro. ¿Y qué es lo que necesitamos
para que esto funcione? ¿Para que este custom hook funcione? ¿Qué necesitamos? Bueno, ya
vemos que necesitamos el fact, ¿no? La curiosidad del gato. Pues la vamos a pasar aquí como
parámetro. ¿Qué más tendríamos por aquí? Pues ahora vemos que este custom hook no está
devolviendo absolutamente nada. Pero sí que necesitamos que devuelva algo. ¿Qué tiene
que devolver? Pues el image URL. Una vez que tiene la imagen que estamos guardando
en el estado, necesitamos que la guarde y que la podamos recuperar. Así que vamos a devolver
un objeto que sea con el image URL. Y con esto, simplemente, ya tenemos nuestro primer
custom hook. Que lo que tiene es un estado interno, que tiene un use effect, que cada
vez que el parámetro que nos hemos pasado, que es el fact, va a volver a pedir los datos,
¿vale? Con las tres primeras palabras. Va a pedir la imagen, va a guardar la imagen
en estado. Y este estado lo vamos a tener aquí disponible. Esto ahora, lo bueno, es que
se convierte en una caja negra. Una caja negra que ya sabemos lo que hace, que es devolver
el image URL con la imagen. Pero es una caja negra porque no tenemos que saber
dentro de este componente realmente cómo funciona. Solo sabemos que como devuelve
el image URL, pasándole el hecho, esto debería funcionarnos. Sin saber qué es lo que hace
dentro. ¿Ves? Está funcionando perfectamente. Lo único que hemos hecho es mover la misma
lógica que teníamos dentro de nuestro componente a una función que se llama
use cat image. Importante de que tiene que empezar por use y que también tiene que
seguir todas las reglas que tienen los hooks que comentamos el otro día. Tiene que
seguir la regla de que no puede estar, no puede estar dentro de un if, ¿vale? No puede
estar dentro de un if. Tampoco puede estar dentro de un while, por ejemplo. No puede
cambiar su posición. Siempre tiene que ser llamado dentro del cuerpo de nuestro
componente. ¿Por qué? ¿Qué diferencia hay entre un custom hook, no? Entre este custom hook,
hook y una función. La diferencia es que dentro de un custom hook podemos llamar hooks.
Tú no puedes llamar un hook en una función normal. Por ejemplo, en esta función que hemos
creado, aquí no podemos llamar al useState porque no tiene sentido. UseState is not available here.
No funciona, ¿vale? Esto sería una función normal. Esta es la diferencia entre una función
normal que no podemos utilizar otros hooks de React y un custom hook, donde sí que podemos
utilizar todos los hooks de React. Ahora mismo solo sabemos dos, pero fíjate que con solo los dos
que sabemos ya hemos podido crear un trozo de lógica reutilizable para nuestro componente.
Podemos utilizar este useState image que cada vez que le estamos pasando un hecho, cada vez que le
estamos pasando un hecho a este useState image, y esto lo podemos utilizar ya en cualquier
componente. No solo aquí. Podríamos utilizarlo en otro sitio, utilizarlo en cualquier lado.
Estamos reutilizando lógica, ¿vale? Ese es el tema. ¿Por qué pasas el fact como objeto?
Muy buena pregunta. ¿Por qué hago esto? ¿Por qué no hago esto? Que también funcionaría.
Podría hacer esto y podría hacer esto. A ver, esto es una buena práctica en JavaScript en general,
y se trata de la extensibilidad de nuestros custom hooks en este caso, o de las funciones en general.
Siempre vamos a querer que nuestras funciones estén preparadas para que se puedan extender
fácilmente. ¿Qué es lo que pasa? Si yo utilizo esto y el día de mañana le pongo un segundo parámetro,
que por ejemplo sea options, ¿vale? ¿Qué va a pasar? Lo que va a pasar es que nuestro useState image,
ahora el fact, ¿vale? Pues aquí tendría options. Imagínate que les os pasamos vacío. Y el día de mañana
alguien dice, ostras, es que también quiero pasarle el límite de palabras. Ah, vale. Pues ahora
tenemos esto. Pues imagínate que tenemos aquí y alguien dice, ah, no, pues el límite de palabras
aquí. Claro. Ya empieza a ser cada vez más complicado y además aquí le puedes poner el nombre
que quieras. Entonces es buena práctica utilizar muchas veces un objeto porque lo que te asegura
es que le vas a pasar, uno, siempre el mismo nombre. Te vas a asegurar que el nombre que estás
utilizando aquí sea fact, que es descriptible, en lugar de utilizar un nombre que no tiene
sentido. Por eso aquí le llaman parámetros nombrados porque estamos obligando que el
nombre sea ese. La segunda razón además es que es extensible porque yo puedo utilizar
options, limit, lo que sea, que independientemente del orden en el que vengan, aquí siempre van
a ser bienvenidos. No va a haber ningún tipo de problema. Esas son las dos razones. Ahora,
no pasa nada. En esta prueba técnica yo creo que no debería haber ningún tipo de problema,
¿vale? Pero solo para que sepáis, esta sería la razón. ¿Y por qué dejas el useState
de la imagen dentro del custom hook? Por silver. Porque es que el estado tiene sentido que
esté dentro del custom hook. Porque si está fuera lo que estaríamos haciendo constantemente,
primero es que necesitamos el estado porque lo necesitamos aquí al useEffect. Lo segundo
es que no tiene sentido aquí ya el estado. Justamente lo que queremos es extraer la lógica y la
lógica, el estado, es parte de la lógica. O sea que tenemos que extraerlo al custom hook.
Ahora lo importante es que esto es una caja negra para nosotros que funciona como queremos
que funcione. Luego el día de mañana igual no es un useState. Igual está utilizando
un estado global o está utilizando otra cosa. Pero lo importante, lo importante es que para
nosotros funciona. Fíjate lo interesante de un custom hook. Mira, lo que vamos a hacer
aquí ahora es que vamos a sacar aquí en el, en service, teníamos services, vamos a poder
tener una carpeta y le vamos a llamar hooks. Y vamos a llamar esto, vamos a llamar
useCatImage.js. Vamos a sacar ahora todo este custom hook que habíamos hecho, lo sacamos
y lo ponemos aquí. Export function. Vamos a importar la useEffect, que lo necesitamos,
y el useState. Perfecto. Ahora que ya tenemos esto, este CatImage lo importamos.
Vale. Lo bueno es que este useCatImage, que ahora funciona, esto, si yo hago cambios aquí,
esto va a funcionar sin problema. O sea, tú aquí podrías hacer tantos cambios como
necesites. Mientras cumplas el contrato que tiene este custom hook, que sería devolver
un objeto con el string, ¿vale? Tú podrías quitar, o sea, podría quitar esto. Podría
quitar todo esto y aquí poner un, o sea, poner siempre la misma imagen. Poner siempre
la misma imagen. Yo podría poner esto aquí y esto, bueno, ahora no se pone en función,
pero debería funcionar. Vale, porque había puesto una coma por ahí. Bueno, está fallando
algo porque no me pilla la imagen, pero funcionar debería funcionar. Es por los espacios que
la lía. Pero lo importante es que cualquier cosa, que hagas un fetching de datos, que hagas
el fetch a otra API, que utilices un estado global, que utilices lo que sea, ¿sabes?
Lo importante es que este custom hook ahora funciona siempre y es reutilizable. Así que lo
hacemos por eso, para que tenga toda la lógica que necesita en un mismo sitio.
Should have a queue. A ver, vale. Ya está, funcionando otra vez. Vale.
¿Qué opinas de la gente que tiene experiencia académica haciendo proyectos personales, pero
no experiencia laboral? ¿Cómo los toman como juniors o trainee? A ver, que es normal.
O sea, si no tienes experiencia laboral, tendrás que tener algo. Y, hombre, tener, obviamente,
proyectos, pues te lo tomas como mejor que la persona que no tiene proyectos. Es que te lo
tomas así. Por cierto, no power. Muchas gracias por regalar cinco subs. Muchas gracias,
amigos. Muchas gracias a todos los que os hayáis suscrito, que no os he dicho nada, pero os
quiero mucho. Entiendo que el custom hook puede devolver funciones como useState, ¿verdad?
Puede devolver, por ejemplo, podríamos devolver el setimature. Esto lo podríamos devolver
sin ningún problema. Claro que sí. Lo podríamos devolver. Pero evitad devolverlo a no ser
que lo necesitéis. O sea, si podéis evitarlo, evitarlo. Si podéis tener el estado interno,
mejor. Si por lo que sea necesitáis tener el estado expuesto, expuesto en el sentido
de que se pueda actualizar desde fuera, pues lo hacéis. Pero en este caso, yo creo que
lo mejor es evitarlo. Porque queremos que no se pueda cambiar el estado desde fuera y
queremos que sea una caja negra, justamente. Vale. Ahora, lo mismo, para que veamos otro
ejemplo más. Porque, bueno, con uno, pues igual alguien dice, ostras, pero has hecho el
ejemplo fácil. Que puede ser, ¿eh? Puede ser. Vamos a hacer este. Que este, pues, un poquito
es lo mismo. Y además este es más interesante porque aquí podríamos reutilizar, podríamos
hacer el custom hook para que el handle click, este es más interesante. Es un poco más
complicado. Aunque sea más corto, es un poquito más complicado, pero es interesante. Mira,
vamos a hacer también esto. Should have a queue. No sé qué dice con esto. A ver. No
sé qué le pasa al que me está dando. Should have a queue. No sé qué dice. ¿Por qué
dice este error? No sé qué se refiere con el error ese. Ah, vale. Se ha quitado. Bueno,
el tema. Vamos a extraer también el primero, este, que parece el más sencillo, pero es un
poco más complejo. Pero vas a ver cómo también podemos exportar una función para
recuperar. Porque fíjate que aquí el handle click necesita hacer el getRandomEffect, el
setFact. Y esta lógica de aquí es la misma que tenemos aquí. Está repetida. Pues esto
lo vamos a evitar con el custom hook. Vamos a poner aquí el useCatFact. ¿Vale? Una cosa
súper importante. Una cosa muy importante. No utilicéis esto. No hagáis esto. No hagáis
esto. UseFetch o useCatFetch. ¿Vale? Porque esto es una mala práctica, ¿no? ¿Por qué
poner useCatFetch o useFetch fact? Vale. Tenéis que evitar en los custom hooks, os estoy diciendo
mucho, es una caja negra, es una caja negra. ¿Sabéis por qué os digo eso? Porque es que
es súper importante que entendáis que los custom hooks no pueden ir atados a la implementación.
¿Qué es la implementación? La implementación es lo que hace por dentro el custom hook. No
podéis darle un nombre que te diga la implementación que tiene. Hay que evitarlo a toda costa, siempre
que podáis. Y lo vais a ver en el curso constantemente, que lo vamos a estar evitando constantemente.
Cuando hagamos estados globales y todo esto, lo vamos a estar evitando. Porque lo que hace
por dentro el custom hook puede cambiar. Si yo le digo useFetchCatFact, parece que siempre
va a hacer un fetch. Y no tiene por qué. A lo mejor hace un fetch, como que a veces,
a lo mejor el día de mañana va a GraphQL, ¿sabes? Lo que sea. Los hooks se nombran JSX o JS.
Se nombran JS. No necesitan JSX porque no tienen JSX. Entonces, no hagáis esto. UseFetchCat.
Puede ser useCatFact, por ejemplo. Puede ser lo que queráis, pero no le dedicáis la implementación.
Por ejemplo, una mala práctica sería decir useReduxGlobalStore. Es que esto tiene bichos.
Porque si tú tienes esto a lo largo y ancho de toda tu aplicación, el día que no utilices Redux,
pues no. Lo que tendrías que hacer es useCat y dentro de un custom hook a lo mejor utilizar
el useGlobal. Pero no lo utilices en todos tus componentes. Tienes que evitar utilizarlo
lo mínimo posible. Entonces, aquí pondríamos useCatFact. ¿Qué sacamos en el custom hook este?
El fact del gato, ¿no? O sea, el estado del gatillo. Y este useEffect para recuperar la cita
al cargar la página. Vale. Esto por un lado. Obviamente esto va a petar ahora.
¿Qué vamos a hacer aquí? Vamos a hacer algo. Vamos a extraer esto. Esto lo vamos a extraer.
Lo vamos a poner aquí un getFact andUpdateReactState. ¿Vale? Aquí dentro tiene sentido que seamos
dentro del custom hook podemos explicar la implementación porque tiene sentido.
Pero aquí vamos a hacer el fetch... Bueno, no el fetch, no. GetFactRandomFact
andUpdateReactState. Bueno, esto es un poco bestia, ¿eh? Pero le podéis llamar
GetRandomFact, andUpdateState o lo que queráis. Hay gente que le gustan los nombres largos
y explicativos. Lo que queráis. Al menos ya lo que tenemos en esta función es que hace
el randomFact, ¿no? Lo recupera y luego, una vez que lo resuelve, actualiza el estado.
Esto es justamente lo que queríamos hacer en el efecto este. Así que lo ponemos así.
Pero también es lo que queremos que haga el botón. Este botón de aquí.
¿Qué podemos hacer en este caso? Lo que vamos a hacer es devolver tanto el fact
como el GetRandomFact andUpdateState. ¿Vale? Vamos a hacer esto de aquí.
Ahora podemos recuperar tanto el fact como el GetRandomFact andUpdateState.
Bueno, el UpdateState, esto no tiene mucho sentido. Le vamos a quitar el nombre. GetRandomFact.
O sea, vamos a dejar así. No, GetRandomFact no. Get...
O Refresh. Le podemos decir RefreshRandomFact. RefreshRandomFact. Me gusta el nombre.
RefreshRandomFact. Porque queramos recuperar uno nuevo, ¿vale? De que le ponemos ese nombre.
Y así aquí quedará mejor. Incluso lo podemos poner un poco más corto.
RefreshFact. Ya que el estado se llama fact. Pues lo ponemos aquí. Así.
RefreshFact. ¿Vale?
Ahora utilizamos este CustomHook que no tiene ninguna dependencia.
Y el RefreshFact. Le decimos que cuando hagamos un clic, pues nada.
Hacemos el RefreshFact. Lo ejecutamos y ya está.
Pero fíjate. Ahora tenemos que cambiar esto.
Porque ahora el fact lo necesitamos para el UseCatImage.
Lo tenemos que poner arriba del ImageUrl.
Porque este fact que irá cambiando es el que vamos a pasar por parámetro aquí.
Que irá cambiando también. Y ya está.
Con esto ya lo deberíamos tener. ¿Vale?
GetNewFact. Y ya está.
Ahora, ¿qué es lo que hemos hecho?
Vamos a repasar esto porque este hook es muy interesante.
Porque no solo estamos como haciendo, tener un estado interno,
hacer el fetching de datos y tal.
Sino que también lo que estamos haciendo es tener un método
que lo que hace es actualizar, es recuperar nuevos datos
y actualizar el estado interno.
Y esto lo estamos dejando para afuera.
Le hemos llamado RefreshFact.
Así, cuando tú quieras, por ejemplo, cuando salga clic en un botón,
lo que puedes es pedir bajo demanda
que se actualice el estado interno de este custom hook.
Pero fíjate lo fácil que es.
Siempre, siempre, siempre que puedas,
evita exportar la actualización del estado.
¿Por qué?
Mucha gente lo que diría es,
ah, pues voy a hacer esto.
SetFact.
Y este setFact, aquí tengo
un
getRandomFact.den
newFact.
Esto, ¿no?
No hagáis esto.
Siempre que podáis,
evitar que el custom hook devuelva la actualización del estado.
Si es algo que internamente puede hacer el custom hook,
mejor.
Porque esa lógica la vais a poder reutilizar en un montón de sitios.
¿Vale?
Así que lo dejamos por aquí.
Lo dejamos como estaba, que tiene mucho más sentido.
Y así el día de mañana, pues, lo hacemos.
Como hemos sacado el otro justamente en una carpeta hooks,
¿no?
Pues lo vamos a sacar también.
El useCatFact.js.
Lo exportamos por aquí.
Bueno, aquí este lo he puesto como una constante.
Voy a hacerlo con una function, ¿vale?
Para que quede exactamente como el otro.
Y vamos a importar aquí.
Tanto el useState como el useEffect.
¿Vale?
El getRandomFact también lo vamos a editar.
Que además, fíjate lo limpio que nos va a quedar ahora esto.
Fíjate.
Fíjate en esto, que esto es una maravilla.
UseCatFact.
Vale.
Fijaos en nuestro componente inicial.
Que teníamos todos los fetch, que teníamos un montón de lógica.
Ahora no hay vista de useState.
No hay ninguna vista de un useEffect.
Y esto es algo súper importante en React.
Normalmente, cada vez que veas un useEffect en un componente de React,
pregúntate si debería ser un custom hook.
¿Por qué?
Porque normalmente los useEffect tienen carga de lógica,
que vas a querer reutilizar,
que vas a querer separar,
y que no vas a querer que esté en mitad de tu componente.
Pregúntate,
¿este useEffect realmente lo podría separar en un custom hook?
Es una pregunta que te va a ayudar un montón y que es súper importante y súper básico en React.
Porque si no, al final, como novato que vas a ser,
tú vas a empezar a meter useEffect por un tubo y se te va a ir de las manos.
No vas a entender justamente de dónde viene cada cosa.
Así que con esto lo que hemos hecho es separar en dos custom hooks parte de nuestra lógica
y lo mejor de todo es que son utilizables de forma conjunta y separada.
Nosotros podríamos crear otro componente aparte,
como por ejemplo,
vamos a crear un componente para que veas lo que acabamos de hacer.
Vamos a poner aquí components y vamos a poner otro,
otro, ¿vale?
.jsx
y lo que tenemos por acá en el imageUrl.
Imagínate el imageUrl.
Vamos a exportar function otro,
otro,
return
y aquí vamos a utilizar solo este, el de fact.
Y voy a poner aquí un random fact.
Fíjate que ya se puede utilizar esto.
No hay ningún problema de que utilicemos este custom hook totalmente separado.
ImageUrl,
esto por aquí,
imageUrl,
hacemos un and aquí para evitar esto,
importamos el use este
y vamos a poner aquí
esto por aquí,
esto por aquí,
por aquí,
vale.
Este otro lo vamos a cargar
debajo.
Vale, bueno,
no ha pillado la imagen.
Me está rompiendo,
o sea,
está rota la imagen
porque random no le gusta.
Vamos a ver qué le pasa aquí al...
cat,
vamos a poner cat
porque sale rota la imagen.
imageUrl,
bueno,
igual le he liado,
¿no?
Vamos a ver qué he hecho aquí.
ImageUrl,
vale,
cat.
porque tenemos que concatenar,
que aquí lo habíamos hecho,
¿ves?
Incluso esto de concatenar,
mira,
esto de concatenar está interesante
porque fíjate que lo habíamos hecho aquí
y ahora esto lo necesitaríamos poner,
pues es que esto está,
esto está,
esto está en la leche.
Los custom hooks son la clave,
son la clave para reutilizar un montón de lógica.
¿Ves?
En este caso,
la lógica que habíamos hecho
de prefijar la URL de la imagen
la habíamos dejado aquí
en mitad del componente,
pero tiene sentido realmente
que esté dentro del useCatImage,
que esta lógica la tengamos aquí
porque es aquí
donde realmente
no necesitamos guardarlo en el estado,
pero cuando devolvemos
el imageUrl aquí,
podemos hacer aquí la concatenación
y de esta forma
nos simplifica un montón
que si nos tenemos que preocupar
de esto o no.
Ahora ya podemos quitar esto de aquí
directamente mucho más fácil
si el día de mañana
cambia esta lógica,
la tendremos en el custom hook
y...
¡Qué bueno!
Bueno,
y ya tendríamos esto, ¿no?
Teníamos aquí la imagen
que sacamos de aquí
y esto que estamos reutilizando
en el otro,
este de aquí.
Y esto lo podemos utilizar
tantas veces como queramos, ¿ves?
Podemos tener más imágenes
con el otro
y estamos reutilizando
el mismo custom hook.
Tienen estados totalmente separados,
cada uno el suyo
y ya está.
Así que ahí es donde puedes ver
un poco la potencia
de los custom hooks, ¿vale?
Vale.
Preguntas.
Preguntas.
El nuevo orden mundial,
ya te digo.
El CatRamp.
Al Junior lo ponen de...
PlotTwist,
al Junior lo ponen de Team Lead.
A ver,
esto...
¿Cuántas clases llevamos de React?
Llevamos tres,
que son seis horas.
Bueno, no seis horas,
no, un poco más.
Ocho horas.
Hombre.
Hombre.
No sé.
Muchas veces me decís,
¿cómo puedo conseguir
mi primer empleo?
A ver, amigos.
No podemos esperar
ir a encontrar
nuestro primer empleo
y de React
solo saber
UseState y UseEffect.
Tenemos que mover las manos.
Saber crear un custom hook
lo puede aprender cualquiera.
No es un tema
de ser súper dotado
ni son temas avanzados.
Os lo digo con la mano del corazón.
No os quiero engañar.
O sea,
no os quiero decir,
sí, sí,
no te preocupes.
UseState,
UseEffect,
tira para adelante.
Hombre.
Amigos.
Necesitamos...
Es que, claro,
luego me venís
que no sabéis
por qué nos contratan.
Hombre,
yo creo que
saber un custom hook,
saber hacer lo que hemos hecho hoy,
creo que es importante.
Creo que es importante.
Un custom hook
es muy fácil de hacer
y es una de las cosas
más fáciles
que podéis hacer.
¿Y no puedes conseguir
tu primer empleo
sabiendo React
sin entender JavaScript?
Es básico.
Claro.
Hombre,
sin saber JavaScript
es difícil
porque React es JavaScript.
Así que...
Pregunta a mí,
¿de una entrevista
estaría mal
usar los snippets
de Visual Studio?
Hay veces que te lo hacen
desactivar,
pero yo creo que
no estaría mal.
¿Los custom hooks
se usan para aplicar
el principio
de inversión de dependencias?
En inversión de dependencias
se podrían utilizar,
pero normalmente
lo que más utiliza
es el contexto.
Esto sigue siendo básico.
La diferencia
es que te tomabas
sin saberlo
y lo aprendías a la fuerza
y ahora lo tienes que saber
antes de entrar.
Claro,
puede ser.
Claro,
es que básico es.
O sea que un custom hook
es una función normalita,
pero con hooks.
Sí,
podríamos decir.
Esta semana
arranqué a trabajar
en Accenture
para un cliente bancario.
¿Qué opinas del rubro bancario
para los devs?
¿Soy dev?
Pues me parece bien.
Mientras pague
Matías las facturas,
súper bien.
Súper bien,
me parece.
Súper bien.
Bueno,
entonces,
preguntas típicas
que suelen hacer
en estos casos,
¿vale?
Las preguntas típicas
que suelen hacer
pues sería más del palo
qué más harías,
qué le harías,
qué tal.
Entonces,
lo más importante
de decir
lo que harías
porque dirían,
oye,
¿tienes más tiempo?
¿A qué le dedicarías
a hacer más cosas?
Lo que tienes que hacer
no se te ocurra decir
hacer más features.
Tendrías que hacer
handling de errores,
handling de errores,
¿vale?
Hacer el handling de errores
que no lo hemos hecho
porque no sé qué.
Yo,
seguramente,
lo que diría
es testing
y hay veces
incluso que te dicen,
ah,
te atreves a hacer algún test
y vosotros
os tenéis que atrever
al menos el más básico.
Entonces,
yo voy a enseñar
pero os invito
a que juguéis
con lo que vamos a hacer
porque,
uno,
es muy fácil
y dos,
creo que vais a aprender
y es súper importante.
Voy a utilizar
Playwright
que es una especie
de cypress
para hacer el testing
al menos el más básico
que se me ocurre.
Vosotros,
si se os ocurre otro,
pues lo hacéis.
Aquí me está preguntando
en qué carpeta hacerlo,
si hacer GitHub Actions,
le voy a decir que no,
que si nos instalo browsers,
le voy a decir que sí,
nos hace la instalación,
¿vale?
Y aquí
nos habrá quedado
la carpeta test.
En la carpeta test
yo voy a borrar los ejemplos
porque no tiene mucho sentido
y en test
ya nos ha puesto aquí
un ejemplo.
Bueno,
¿cómo funciona esto?
Lo que funciona
es bastante fácil,
no te preocupes
porque vas a entender
un montón de cosas.
Obviamente,
no vas a tener mucho tiempo
para hacer los mejores tests
de la vida,
pero tú le dices,
yo lo que haría
es el test más importante,
que es un end-to-end
para asegurarme
que al menos sale,
para que le dé algo
al usuario
y me voy a asegurar
que al menos tenemos
un texto
y que sale una imagen.
Claro,
no puedes saber
si la imagen es correcta
y tal,
pero al menos
ver que se ha renderizado
algo en la página,
que hay un texto
y una imagen,
eso ya es algo
y eso que puede parecer
una tontería
te puede evitar
muchos de los errores
que puedes tener.
Entonces,
vamos a poner
app shows
random fact
and image.
Vamos a utilizar aquí
el localhost URL
que tenemos aquí.
Esto puede ser configurable
con variables de entorno,
nosotros lo vamos a hacer
por ahora sí,
¿vale?
Le tenemos que decir
a qué ruta tiene que ir.
Bueno,
la ruta a la que tiene que ir
sería esta,
localhost URL.
Y ahora aquí
deberíamos empezar
a decirle
qué es lo que tiene que hacer.
Normalmente,
esto funciona todo
con promesas.
Entonces,
tenemos que decirle,
vale,
voy a recuperar
el texto
y la imagen.
Como puedes ver,
no hemos utilizado
ninguna idea,
ninguna clase.
Como queremos hacer
un test
y es de algo muy pequeño,
lo podemos explicar
y decimos,
bueno,
como es bastante sencillo
y quiero que sea semántico
y accesible,
vamos a utilizar,
vamos a recuperar
nuestros elementos
fácilmente utilizando
el page,
en lugar del text content
que no sabes
cuál es el random fact
que le han puesto,
vamos a poner
get by role.
Vamos a decirle,
quiero que me recuperes
de la página
el parágrafo que encuentres.
Obviamente,
el role de la p
es párrafo,
así que va a encontrar
este de aquí.
¿Vale?
Importante,
no se te olvide
de los awaits.
Luego,
la imagen
sería exactamente lo mismo,
solo que el role
sería diferente,
porque en este caso
sería imagen.
Obviamente,
esto no funciona así
porque esta aplicación
es muy sencilla.
Si no,
tendríamos que recuperar
del page
dentro del selector
tal,
recupérame
el role párrafo
o cosas así.
O puedes utilizar
nombres accesibles,
atributos,
el data test ID
típico.
Por ahora,
lo vamos a hacer así
porque queremos escribir
lo mínimo posible
y porque, bueno,
tampoco pasa nada.
Recuperaremos
el text content,
¿no?
Vamos a esperar
el text content
de nuestro párrafo.
De nuestro párrafo,
vamos a esperar
el contenido del texto
también,
asíncrono.
Y vamos a recuperar
también el image source.
Para esto,
vamos a recuperar
el atributo source
de la imagen,
¿vale?
Y aquí lo que podemos
hacer es esperar
que el text content
no sea nul
o al menos
que el texto content,
el length,
sea mejor,
mayor,
¿no?
To be greater
than zero.
Y la imagen,
bueno,
podremos decir esto
o puede ser un poco
más allá,
que puede ser interesante,
decirle que la imagen
tiene que empezar
justamente
con el prefijo.
Ya en menos ahí
ya estás
viendo algo
más interesante,
¿no?
Decirle, vale,
tiene que empezar
con el cat prefix
image URL.
Así te aseguras
que estás cargando
la imagen correcta,
¿no?
Esperamos que esto
to be truce,
¿vale?
Que sea truce.
Y con esto,
a ver,
no es el mejor,
no son los text
más exhaustivos
del mundo,
pero son 18 páginas,
hay 18 páginas,
18 líneas
que hemos hecho
en un momento
un test end-to-end
para al menos probar
que nuestra página
se está renderizando.
Vamos a ver si funciona,
hacemos play write test,
vamos a ver si me equivoco
en algo,
vale,
no pasa nada.
Me dice que el require
no está definido
en más script.
Esto es súper importante,
¿ves?
Por eso es súper importante
muchas veces
el tema que te salga un error
y que sepas
lo que significa.
Lo que está pasando aquí
es que el play write
¿ves?
está utilizando requires
y nuestro proyecto
es en más script modus,
está utilizando imports.
Para que esto funcione,
lo que deberíamos hacer aquí
es cambiarle la extensión
a cjs,
que es de common.js.
¿Mido en rn
se puede hacer igual e2?
¿O cómo sería?
Se puede utilizar,
se puede hacer,
pero no con play write.
Lo tienes que hacer
con otras herramientas
y puedes hacerte
ese en tu en igual.
Hay un montón de herramientas
que están preparadas
para eso.
Y luego,
¿qué más?
Este play write,
bueno,
si no también,
ah, vale,
este ya estaría
y en este vamos a cambiar
este require
para utilizar el import.
From,
¿vale?
Y con esto
ahora vamos a probar.
Vale.
Obviamente,
no fíes de un test
que pasa como si nada.
Vamos a hacer una cosa.
Vamos a decir
que empiece con hola.
¿Vale?
Vamos a ver
que nuestros test
petan
porque si no,
al final
no es nada interesante.
Si vemos que no peta,
¿vale?
Vemos ahora que peta,
¿no?
Nos está diciendo,
ah,
es que esto está petando.
Podríamos mirar
en un console.log
porque está petando.
O sea,
está chulo
porque así
nos aseguramos
de que nuestros test
realmente hagan lo importante.
Podemos poner aquí
un console.log
para ver realmente
el text content
y el image source,
¿vale?
Vamos a mirar esto por aquí
y a ver aquí,
¿vale?
Ves,
text content
y el image source.
Esto no hace falta
que lo pongamos
en el console.log,
esto es solo para asegurarnos
que realmente está funcionando,
pero con esto
ya tenemos un test
end-to-end
que está entrando
en la página
y revisando
y aquí tienes tus ejercicios.
Tu ejercicio es
cómo harías
de detectar en el test
que realmente
cuando hacemos click
cambia la imagen.
Ya te digo
que vas a tener que guardar
algunas variables
que es un poquito tricky
pero está interesante.
Pero bueno,
con esto ya lo tienes.
Te voy a subir,
ah,
esto lo he puesto aquí
en prueba técnica
y claro,
esto,
a ver un momento,
prueba técnica,
voy a subir esto
al pedazo de repo
que tenemos.
Vale,
ya está,
esto aquí,
esto lo vamos a quitar
de aquí,
nos vamos a,
claro,
esto la hemos liado,
seguro.
Vale,
aprendiendo
React
porque ahora está
React
prueba técnica,
ah,
esto tenía que estar
dentro de Project,
así que
React
prueba técnica
Projects,
vale,
React
prueba técnica,
y ahora aquí
tendríamos que hacer
la instalación
en PMI Store
de esto
y ya lo tendríamos.
Pues os voy a subir esto,
espero que
add
new
project,
vale,
ay no,
no me digas
que tenía que hacer
un pull antes.
Vale,
puxamos,
ahora sí que me deja,
vamos a llevarnos aquí
todo nuestro proyectito
que tenemos por aquí,
quitamos esto,
esto fuera,
y esto fuera,
follower,
y este es el 04.
Pues ya tenemos
cuatro proyectos,
hombre,
y el de hoy
bastante potente,
bastante potente,
use new folder name,
guardamos,
puxamos esto,
y esto lo tenéis
en aprendiendo
React,
en este repositorio
de aquí,
donde estamos siguiendo
todo el proyecto,
os lo dejo también
para que no os lo perdáis,
¿vale?
Os recomiendo
que os veáis otra vez
el string,
que intentéis hacer
la prueba técnica
ustedes mismos,
¿ok?
He visto una carpeta
llamada midu
xxangular,
no creo,
¿qué metodología ágil
recomiendas
para un proyecto
unipersonal?
Ágil,
extreme programming,
extreme programming,
por ejemplo,
¿qué es esos shortcuts
de Git en mi humilde
window?
Ya te digo,
pues amigos,
esto es todo,
mañana,
mañana no hay directo,
o mañana no hay directo
pero habrá el viernes,
y os explico