Eliminando avisos en React e introduciendo otros bugs

En el componente Search podemos ver como se utiliza una función de tipo dobounce(). Las funciones debounce() fuerzan a una función a esperar un cierto tiempo antes de ejecutarse de nuevo. En este caso conseguimos que no se ejecute una llamada a la API cada vez que el usuario introduce un caracter en el campo de búsqueda. La llamada se realiza una vez que el ususario para de teclear.

Al magen de esto, veamos  alguno de los problemas con los que nos podemos encontrar al utilizar el hook primitivo useEffect.

Con esta comprobación conseguimos que se realize una llamada la primera vez que carga la página, si existe un termino de búsqueda y no existen resultados de búsqueda realizamos la misma.

if (term && !results.length) {
search();
}else{
Al utilizar esta pieza del state, denominada results, para realizar tal comprobación dentro de la función useEffect, si comprobamos la consola podremos ver que existe un aviso.
React Hook useEffect has a missin dependency: ‘ result.length’
Either include it or remove the dependency array react-hooks/eshaustive-deps

Dentro de la función useEffect hemos añadido la pieza del state denominada results.length. Cada vez que referimos una pieza de stado o una prop dentro de la función useEffect, React o más especificamente una regla definida dentro de React(ESLint) quiere que referenciemos esta información dentro del array de dependencias.

Si declaramos results.length en el sitio indicado, el error desaparece.

Existiran toda una serie de escenarios en los que utilizaremos el hook primitivo useEffect y al no incluir en el array de depenencias todas aquellas props o piezas de estado utilizadas seremos conducimos a lidiar con extraños y complicado problemas dificiles de encontrar. Esta regla mostrada anteriormente nos ayudara a evitar este tipo de problemas.

Pero, aunque esta regla es muy bien intencionada y nos ayuda a evitar muchos problemas que nos irán apareciendo por el camino, el aplicarla nos puede conducir a crear otros problemas.

Veamos en este caso cual es el ‘bug’ que se a creado tras cumplir con la solicitud de la regla.

Cuando recargamos la página, solo se debería ejecutar una llamada a la API pero se realizan 2.

El diagrama que vemos a continuación ilustra perfectamente cual es el problema.

Al cargar la página tal y como hemos definido en el codigo al existir un termino de búsqueda y no existir resultados de búsquedas (results.length is zero ) se ejecuta una llamada. El problema es que tras realizar esta llamada el valor de results.lenght cambia y como esta pieza del estado esta incluida en el array de dependencias de la función useEffect este cambio provoca que la función se ejecute de nuevo realizando una segunda llamada.

Debounce

Para solucionar este problema debemos cambiar la estructura de nuestro código. Vamos a introducir una nueva pieza en el estado del componente denominada: debouncedTerm. Por otra banda, en vez de utilizar una sola vez la función useEffect la utilizaremos 2 veces

En una de ella tendremos la pieza de estado debouncedTerm dentro del array de dependencias y en la otra la pieza de estado term. Ya no referenciaremos los resultados dentro de la función useEffect.

}, [debouncedTerm]);
}, [term]);
Debounce
Debounce

Esta es la solución final.

Ya no tenemos avisos en la consola ni existe el bug indicado.

0 comentarios

Dejar un comentario

¿Quieres unirte a la conversación?
Siéntete libre de contribuir!

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *