logo

midudev


Transcribed podcasts: 146
Time transcribed: 5d 6h 19m 9s

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

Ya tenemos esto, ¿no? Pero después de crear una nueva nota, además, si te has fijado, ¿no? Lo que me gustaría al crear una nota, yo tengo aquí, le doy a new note, entonces me aparece este formulario para crear la nota.
Yo pongo aquí crear mi nota y le doy a save. Pues además de cerrar, de que este input desaparece el contenido, me gustaría que desapareciese el formulario como si le hubiese dado a cancel y se cerrase automáticamente.
¿Cómo podemos hacer esto? Porque esto, ¿quién maneja realmente esto? Pues esto lo está manejando nuestro componente Togable. ¿Cómo hacemos para, de alguna forma, simular que le estamos dando clic aquí?
¿Cómo podemos hacer esto, no? ¿Cómo podemos hacer que en este punto en el que hacemos el handle submit y hacemos esto de cerrar, de añadir la nota y limpiar el input, aparte, nos cierre eso automáticamente?
Esto es un reto que muchas veces mucha gente pues le cuesta en temas de React y en normal, porque React no está muy preparado para hacer este tipo de trabajo imperativo.
De hecho, normalmente, y esto es algo que puede ser interesante, normalmente suele ser una mala práctica, ¿ok?
Y lo que vamos a ver, yo no te lo recomendaría. Si puedo, siempre lo evitaría al máximo.
Es verdad que hay veces en los que estás trabajando, por ejemplo, con librerías de terceros o cosas externas que no puedas controlar, que te ves un poco abocado a trabajar de esta forma, de una forma imperativa.
Pero como ya dijimos en clases anteriores, React trabaja de una forma declarativa.
Por lo tanto, cuando trabajamos de forma imperativa, que es como forzar a, sin decirle lo que tiene que hacer, sino llamar tú al método, suele ser un poco problemático.
Pero te lo voy a explicar por qué. Uno, muy poca gente en realidad sabe hacerlo. Dos, porque saben el contenido. Y tres, porque se puede ver un poco una posibilidad que puedes tener que te puede salvar de más de un problema con React en algún sitio.
Lo primero que vamos a hacer es ver dónde queremos utilizar justamente, dónde vamos a llamar a esto de hacer la llamada imperativa.
Pues lo vamos a hacer aquí, en el NodeForm. Ahora, este NodeForm, lo que necesitamos es tener la posibilidad de llamar a un método que haya dentro de este componente, desde el componente padre.
¿Cómo podemos hacer eso? Pues lo primero que vamos a hacer es crear una referencia. Lo vamos a ir utilizando el hook useRef.
El useRef es un hook que lo que te permite es guardar en un objeto una referencia que no va a cambiar entre renderizado. Tiene un montón de utilidades y una de ellas es la que vamos a ver ahora.
Normalmente, las referencias se pueden utilizar, por ejemplo, vamos a utilizarla aquí directamente, vamos a llamarle ref, useRef y lo ejecutamos aquí.
Puede ser muy interesante utilizar una referencia para elementos del DOM. Por ejemplo, este H3.
Le podemos decir, vale, pues este H3, vamos a guardar la referencia en el componente ref. Esto puede ser un poco raro, ¿no? Porque ves ref y ref, pero entonces déjame que le cambie aquí.
Element ref y vas a ver dónde va cada cosa. Ref es una propia especial que es la que te va a decir, vale, pues voy a guardarte la referencia de este elemento,
que básicamente es el DOM element, en esta referencia de React. Si ponemos un console.log del element ref para ver qué es lo que tiene y volvemos a nuestro proyecto,
podemos ver que al principio la referencia es undefined. ¿Por qué? Porque la primera vez todavía no se ha renderizado este H3.
Como la primera vez no se ha renderizado, ¿no? Va por aquí, element ref, vale, pam, y entonces haces el console.log, pero todavía no se ha renderizado.
¿Qué pasa? Que después, cuando se actualiza por primera vez y se renderiza, pues por fin ya tenemos aquí que es un H3.
Si nos ponemos encima, ¿veis? Al darle clic ya me lleva directamente al elemento del DOM. Y tenemos toda la información.
O sea, se refiere a este elemento del DOM, ¿veis? Me lleva a él. Esa es la referencia que tenemos ahí.
¿Qué pasa? Que en nuestro caso no es solo que queremos hacer esto. Esto puede tener un montón de utilidades, como por ejemplo,
puedes decir, vale, pues ahora que tengo esa referencia de este elemento, voy a ver cuánto mide client width.
O puede ser que quiero escuchar un evento. Puede ser que hagas un ATV listener. No es la forma correcta normalmente de trabajar,
pero ya te digo que a veces te puedes ver forzado o forzada a hacerlo así.
Entonces, en este caso es todavía un poco más problemático, porque la referencia no es de un elemento del DOM.
Es de un componente, porque como te he dicho, quiero el togable, quiero llegar a entrar de alguna forma aquí y poder ejecutar algún tipo de código.
¿Cómo lo podemos hacer? Pues es un poquito más complicado. Con los elementos del DOM es bastante fácil, porque hemos visto cómo lo podemos hacer.
En el caso del togable, yo voy a intentar poner aquí la referencia. Voy a poner aquí togable ref.
Voy a cambiarle el nombre a la referencia. Vamos a ponerla por aquí.
Y si yo aquí ahora hago un console.log, vamos a ver qué es lo que tenemos aquí.
Vamos aquí otra vez. Vamos al console.log. Vale.
Ya me está chivando. Ya me está diciendo, oye, aquí hay una cosita que tienes que tener en cuenta.
Y es que la primera vez es undefined y la segunda vez es undefined.
O sea que no está guardando la referencia como lo estaba haciendo antes. No está funcionando bien.
Entonces ya me dice, mira, los componentes funcionales no se le puede dar una referencia así por así.
De hecho, con los componentes que eran clases sí que se podía. Pero bueno, en este no se puede.
Entonces, si quieres intentar acceder a una, tienes que utilizar el react forward ref.
¿Qué es lo que hace esto? Esto es un método especial que tiene el react que tienes que importar desde aquí, forward ref.
Que lo que hace es que a un componente funcional como este, el togable, lo que hace es que cuando le llega esa prop ref,
lo que va a hacer es llevar esa prop con el valor correcto hacia arriba.
Así que tienes que hacer este forward ref.
¿Qué podemos hacer para que esto quede un poquito más legible?
Vamos a cambiar esta función, lo vamos a poner con una const que sea togable, igual.
Y aquí lo que puedes hacer justamente es utilizar este forward ref.
Forward ref.
Forward ref.
Aquí le llega por un lado las props, que son las que tenemos, y luego llegaría la ref.
Y aquí lo que tenemos que hacer es cerrar esto.
Y vamos a exportar el togable.
Y ahora lo repasamos una vez más, ¿vale?
Forward ref tiene que envolver el componente de react, que como puedes ver es lo que estamos haciendo aquí.
Y que es lo interesante, que de alguna forma le podemos pasar, una vez que hacemos esto,
le está llegando como segundo parámetro la referencia.
Así que esta referencia ahora sí que la podemos utilizar para hacer algo.
En este caso le está llegando la referencia que le estamos pasando por arriba.
Y necesitamos hacer esto para poder acceder a ella y cambiar o hacer alguna cosa con ella.
Eso sería la mitad del trabajo todavía que hemos hecho, ¿vale?
Con este forward ref estamos consiguiendo de alguna forma que tengamos esta referencia
que antes teníamos por aquí que no nos servía para nada y ya está tomando vida.
Aunque podemos ver que todavía aquí vemos undefined, no parece que tenga nada,
pero ya no tenemos el wording.
O sea, hemos dado un paso hacia adelante, ¿no?
Parece que algo estamos haciendo.
Y es que ahora sí que tenemos acceso a esta red dentro de este scope.
Podemos hacer algo con esta referencia.
¿Qué es lo que tenemos que hacer?
En este caso lo que queremos hacer justamente es poder llamar a un método que nos cierre esto, ¿no?
O sea, queremos que este estado nos cambie cuando llamemos a ese método desde el padre, ¿vale?
Fíjate la diferencia, ¿no?
Porque normalmente si este estado lo tuviésemos en el padre sería mucho más fácil.
Pero es que aquí queremos mantener el estado aquí en el togable y queremos cambiarlo desde el padre
sin cambiarle las props y tal, ¿no?
Queremos llamar a un método de forma más imperativa.
Bueno, pues vamos a ello.
Lo primero, vamos a crear un nuevo método que le vamos a llamar toggle visibility.
Y este toggle visibility lo único que va a hacer es poner set visible, lo pone visible, le cambia.
Si está true lo pasa a false y si está en false le pasa a true, ¿vale?
Ahora que tenemos este método, lo que tenemos que hacer es utilizar otro hook que se llama
use imperative handle.
Ahora, este hook es un poco especial, es bastante complejo, tiene un montón de historias,
pero lo importante es que es un hook de React que se usa para definir funciones en un componente
que se puede invocar desde fuera del componente, ¿vale?
Eso sería lo más claro que tienes que tener y que no va a cambiar su valor a no ser que tú se lo indiques
con las dependencias.
Piensa en el use effect, ¿no?
En el use effect, cuando tenemos un use effect, tiene aquí unas dependencias que hace que se ejecute esto
solo cuando cambian estas dependencias.
Pues el use imperative handle sería un poco lo mismo.
Es el crear esta función que se puede llamar desde fuera de un componente, del propio componente
y que solo va a cambiar cuando le digamos en esas dependencias.
Es un poco complejo, es verdad, pero cuando veas cómo funciona y tal, pues dirás, vale, más o menos lo entiendo.
¿Cómo se puede hacer esto de que se pueda llamar desde fuera de una función?
Pues lo que hacemos es llamarlo, use imperative handle, y al primer parámetro le decimos
dónde tiene que guardar esta función que queremos ejecutar desde fuera de este componente.
¿Dónde la vamos a guardar?
Pues ya te lo puedes imaginar, ¿no?
Para eso hemos hecho algo lo del ref.
Lo vamos a guardar en el ref.
Y lo que hacemos es crear una función que lo que tiene que devolver es un objeto.
Bueno, podemos hacerlo así, así, así.
Podríamos hacerlo de otra forma, pero bueno, pero ahora vamos a hacer así.
Que se devuelva un objeto que vamos a poner el toggle visibility.
Lo que va a pasar aquí es que lo que devuelve esta función, que es este objeto de aquí,
es lo que se va a guardar en la referencia.
Y vamos a tener acceso a ello.
Y eso va a ser los métodos que estamos utilizando en el use imperative handle,
que van a ser los que van a estar disponibles fuera del componente para utilizarlos.
Justamente el toggle visibility es el que necesitamos para cambiarle la visibilidad de este componente.
Así que esto es justamente lo que queremos hacer.
Lo vamos a dejar así por ahora.
Guardamos los cambios.
Y ahora, bueno, estoy viendo que estos son clics en realidad.
Los podríamos cambiar, ¿no?
Este lo podríamos poner así.
Y ya, pues, aprovechamos el componente que hemos creado
para que cambie la visibilidad siempre con la misma función, que es esta que hemos hecho aquí.
Y ya está.
Y de esta forma debería funcionar exactamente igual.
Si no, pues, ahora nos daremos cuenta de cuál es el problema.
Ahora que tenemos todo esto.
¿Para qué hemos hecho todo esto?
Era para que cuando creamos una nota se pueda cerrar automáticamente, ¿no?
¿Cómo hacemos con el toggle visibility?
Vamos al node form.
Y ahora aquí en el set new node y tal, lo que queríamos es que aparte de borrar el contenido del input,
lo que vamos a hacer es utilizar el toggleref.current.
Current es el valor actual que tiene la referencia.
Esto no es una cosa que le hemos puesto a nosotros.
Esto es que siempre que tú creas un userref de esta forma,
lo que estás haciendo es que togable, cuando se le cambia su valor,
siempre lo tienes que acceder por current.
O sea, que vamos a tener current, punto, y aquí teníamos toggle visibility.
Y aquí ejecutamos nuestro método.
Guardamos los cambios y vamos a ver si funciona.
Vamos a darle a new node.
Probando.
Bueno, aquí ocurren.
Esto es porque cada vez que actualizamos el estado, se vuelve a actualizar el estado,
el componente, se vuelve a renderizar.
Hemos puesto un console.log por ahí.
Le voy a dar a save.
Y como podemos ver, se ha cerrado automáticamente.
No se ha cerrado automáticamente, sino que nosotros le estamos diciendo de forma imperativa
que se ejecute ese método.
Esto se podría hacer de otras formas, ¿vale?
Pero me parece muy interesante esto.
Uno, porque es algo que no se ve mucho.
Hay muchos cursos de React que no explican esto.
Dos, porque realmente puede tener una utilidad, como te digo, para ciertos componentes.
Uno, que no controlas tú.
Y dos, a veces, pues que eso, que están muy lejos, como en este caso, ¿no?
Imagínate que te dice alguien que hagas esta funcionalidad.
Este componente es muy grande y te cuesta mucho refactorizar.
Pues esto puede ser una buena forma de hacerlo.
Otras formas que podrías hacer esto.
Una forma que podrías hacer, en lugar de utilizar todo el tema de referencia,
y que a lo mejor podría ser una buena práctica,
pero entonces tienes otro problema, que sería la fuente de la verdad en React,
que es un tema interesantísimo, y que ya veremos en otro momento en detalle.
Pero que sería, básicamente, pasarle una prop nueva, ¿no?
Lo que podríamos hacer es que le pudiéramos pasar aquí a Togable una prop,
que sea show, por ejemplo, y pasarle aquí un valor, ¿no?
Y que vaya cambiando.
Pero ¿cuál es el problema?
Que este show, si se lo pasamos desde fuera, tendríamos dos fuentes de la verdad.
Una, la que le pasa por props, y otra, la que tiene interna.
Porque este, bueno, le he llamado show, pero lo vas a ver más claro aquí, ¿no?
Visible.
Imagínate que tú le puedes pasar desde fuera el visible,
y también desde dentro tienes un estado visible.
¿Esto qué quiere decir?
¿De cuál se tiene que fiar?
¿Del que le llega por props o del estado interno?
¿No?
Entonces, ya ves aquí que tiene un conflicto.
Este suele ser uno de los grandes problemas que te vas a encontrar en React,
que es la fuente de la verdad.
¿De dónde le llega realmente cómo se tiene que comportar?
¿Desde las props o desde el estado?
Normalmente, esto es una cosa que vas a querer evitar.
Igual le puedes poner, pasar un estado inicial por props.
Esto se lo puedas utilizar aquí, y en lugar de ser false, que sea el estado inicial.
Pero a veces esto te vas a encontrar que vas a querer cambiar desde fuera el estado interno,
y vas a tener problemas.
Pues esto puede ser, el forward ref que hemos visto, el ref y todo esto,
puede ser una forma que una vez que lo dominas, te puede salvar la papeleta.
Si no, eso, con efectos, o si no ya, con temas de estados globales, y cosas así,
que también pueden ser muy interesantes.
Pero entonces, tu componente, de alguna forma, ya no está tan bien encapsulado,
y depende de trabajar dentro de un estado global.
Fíjate la diferencia, ¿no?
Que lo interesante, justamente, de tener estos componentes pequeños,
es que se puedan utilizar en cualquier sitio.
Si de repente, ya lo estás anclando a un estado global,
que lo veremos en clases posteriores,
pues te estás rompiendo, de alguna forma, la encapsulación del componente.
Al final hay un montón de estrategias, esta es una de ellas,
y creo que está bien que la sepas, que la entiendas, que la veas,
porque ya te digo que a veces te puede salvar la papeleta.
Muy bien, hemos visto, si te has quedado hasta aquí, muy bien.