Ahora, este es engañoso, porque he notado en nuestro caso de uso también, teníamos un componente en el que teníamos dos listeners diferentes. Uno era un listener de clic, y el otro era el listener en la pulsación de tecla, que realizaría la misma acción, pero estaban separados. Y debido a eso, estaban llamando a la, digamos, acción principal usando dos funciones diferentes. Sucede mucho cuando tienes una base de código grande, ¿verdad? Así que lo que terminó sucediendo es que el clic del mouse, el listener para eso, estaba usando valores de una ubicación diferente, y la pulsación de la tecla enter estaba usando de una ubicación diferente, lo cual está bien, ¿verdad? Deberían estar obteniendo los mismos valores, llamarían a sus propias funciones, realizarían sus efectos secundarios, y luego realizarían la acción común. Pero el problema que estaba allí era en la pulsación de tecla, el valor que estaba obteniendo, lo estaba leyendo de un estado, y deberías saber, nuevamente, el mismo modelo mental. Siempre que defines un listener o cualquier cosa en React, capturará el valor de los estados que existen en ese punto particular. ¿Verdad? Así que cuando el listener fue registrado, capturó los valores en ese punto. Así que cuando se ejecutó, idealmente debería haber tomado los valores más recientes, pero no lo hizo, ¿verdad? Tomó los valores antiguos. Y fue algo que no notamos porque el efecto secundario fue mío. Pero más adelante, cuando nos dimos cuenta, fue cuando descubrimos que, está bien, esto puede impactar. El impacto podría ser peor, ¿verdad? Porque podrías tener muchas acciones siendo realizadas sobre él, tal vez algún conteo de valores, o tal vez algunos datos analíticos, y eso se corromperá, y podrías no darte cuenta. Así que veamos un ejemplo.
Así que aquí, si ves, solo tengo un botón que incrementa un contador, y tengo un listener añadido en enter. Digamos que lo incremento a 6 y presiono enter. Así que ves, el atajo de tecla enter vio el valor 0, pero el estado real era 6. ¿Por qué? Te mostraré el código. Es bastante estándar, ¿verdad? Solo tengo un estado y uso un efecto de un manejador que en la pulsación de tecla enter, registraría el valor. ¿Ves el error? El error está aquí en las dependencias, no tengo nada mencionado, ¿verdad? Es un array de dependencias vacío. Así que básicamente significa que este efecto se ejecutará solo una vez cuando el componente se monte. Cuando el componente se monta, el valor del estado es 0. Así que no importa cuántas veces lo incremente, el valor del estado cambiará, pero esta función, la función que definimos dentro del efecto, siempre, siempre verá 0, no importa qué. ¿Cuál es la solución? Hay muchas maneras de solucionarlo. Una de esas maneras es simplemente usar un ref, ¿verdad? Hay dos maneras, en realidad, muchas más para ser honesto, pero una manera limpia que descubrí es usar un ref. Así que si ves, he creado un ref, ¿verdad? Y en el efecto, solo he puesto una dependencia en el estado, cada vez que cambia, el valor del ref cambiará, ¿verdad? Así que cuando presionas enter, básicamente solo tomará ese valor. Otra opción podría ser cambiar el array de dependencias y agregar el estado aquí, pero la razón por la que no se recomienda aquí es que cada vez que el valor de este estado cambia, el listener será destruido y se creará un nuevo listener. Eso es mucho trabajo extra. Solo usa refs para este propósito exacto. Déjame mostrarte ahora. Aquí estamos haciendo el código corregido, que es este. Así que digamos que lo aumento a seis y presiono enter, ves, lee el valor correcto, es tan simple como eso.
Comments