Intro
En pleno 2021 la gran mayoría de los desarrollos hechos en react usan hooks, los primeros, más básicos y los que prácticamente usaras en el 100% de tus desarrollos sin lugar a dudas son useState
y useEffect
; pero muchos dev olvidan que hay otros hooks bastante interesantes, menos conocidos, pero igual de importantes para aplicarlos a casos de uso específicos, uno de ellos obviamente es useRef
.
Tratemos de comprender las bases de este hook, como funciona, y sobre todo lo más importante a mi criterio: cuando usarlo.
Sintaxis
- Se lo debe importar como cualquier otro hook. ```js
import React, { useRef } from 'react';
* Su declaración es sencilla:
```js
const variableDeReferencia = useRef(valorInicial);
Por ejemplo:
const inputRef = useRef();
La constante
inputRef
almacena una referencia al DOM que no tiene valor inicial.
Para poder enlazar nuestra referencia, por ejemplo, a un input, se usa la propiedad ref
<input type="text" ref={inputRef} />
Ahora nuestra variable
inputRef
tiene una referencia directa al input, gracias a la propiedadref
.
Ahora bien, si imprimimos por consola el contenido de la variable inputRef
veremos que nos regresa un objeto con la propiedad current
y dentro de ella la referencia al input, dicha referencia tiene en su interior todas las propiedades que pueden ser usadas en un input de tipo text, como por ejemplo: className
, value
, id
, name
, placeholder
, entre otras.
En este punto ya podemos manipular de manera directa dicho input.
useRef()
casos de uso
Este hook puede usarse en 2 casos específicos:
- Acceder al DOM de manera directa Cuando necesitamos acceder a un elemento HTML del DOM, en vanilla js haríamos algo como esto:
<input type="text" id="mi-input" />
const input = document.querySelector("#mi-input");
// o también esto:
const input = document.getElementById("mi-input");
Este código es correcto pero cuando de proyectos grandes se trata esta sintaxis será muy complicada de mantener, por ellos y por muchos motivos más existen librerías como react que nos ayudan a manipular el DOM de una manera un poco más abstracta. Por ello existe el hook useState
que permite crear variables de estado para poder usar el Virtual DOM de react.
Ahora bien, useRef
accede a elementos del DOM de manera directa, sin aprovechar las bondades que nos da react, entonces, ¿por que quisiéramos hacer algo así? ¿No tiene mucho sentido verdad? Por ahora quédate con este pequeño concepto, con los ejemplos podrás comprender mejor.
Ejemplo #1
Después de esta extensa pero necesaria intro, veremos un poco de código, enlazaremos un input a una referencia e imprimimos el valor del input por consola.
Ejemplo #2
Al tener un formulario, podemos darle focus
automatico al primer input cuando la página se renderiza por primera vez:
Puedes probar recargando la página, siempre el primer input tendrá el foco por defecto.
Ejemplo #3
Podemos añadir una clase CSS a un elemento del DOM apretando un botón:
NOTA: Considere estos primeros ejemplos como ejemplos de papel o de juguete, no se debería usar el hook de esta manera, solo son ejemplos para ilustrar y comprender cómo funciona useRef
.
-
Crear una variable mutable persistente entre renders
Este punto es el caso de uso más realista para usar
useRef
, los ejemplos anteriores podrían ser resueltos de otra manera sin necesidad de importar y usaruseRef
, ahora veremos ejemplos donde su uso es necesario.
Ejemplo #4
Al hacer una llamada una API es posible que intentemos renderizar componentes condicionalmente, por ejemplo:
En
<App />
renderizamos condicionalmente el componente<Users />
<Users />
hace una llamada a la API JSON placeholder para obtener 10 usuarios de prueba y pintarlos en pantalla cuando le damos al botónMostrar / Ocultar
Solo para el ejemplo simulamos que la respuesta de la API será de 4 segundos (lo que es una barbaridad de tiempo)
Imaginemos que le damos click al botón, empieza a correr los 4 segundos establecidos, pero antes de que concluya y podemos ver los usuarios en pantalla, le volvemos a dar al botón,el programa seguirá funcionando pero nos aparecerá un horrible error en la consola:
Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
En cristiano este error mas o menos nos dice que intentamos actualizar el estado de un componente desmontado, y no da una pista: usar la función de limpieza que el hook useEffect
Ahora bien, podemos resolver esto usando un useRef
para mantener la referencia del componente y solo realizar actualizaciones de estado cuando este se encuentre montado en la aplicación.
La solución se la puede ver a continuación:
Intentaremos explicar un poco:
Creamos una variable de referencia
isMountedRef
que empieza comotrue
, esta variable representará al componente<Users />
cuando esté montado.Ahora en el
useEffect
usamos unreturn
para MUTAR
el objeto y cambiar el valor afalse
, osea, componente<Users />
cuando esté desmontado.Ahora con un if, solo haremos la petición con
getUsers
cuandoisMountedRef
seatrue
, dicho en otras palabras, sólo cuando el componente esté montado.
De esta manera puedes hacer peticiones a API's un poco más seguras y confiables para evitar problemas con el servidor cuando estemos en producción.
Referencias
Conclusiones
-
useRef
es un hook que permite la manipulación directa de elementos del DOM. -
useRef
no usa el virtual DOM de react. - Para enlazar
useRef
a un elemento HTML, dicho elemento debe tener la propiedadref
con el valor de la variable de referencia. -
useRef
siempre regresa un objeto mutable con una única propiedadcurrent
. - Puedes usar un
useRef
para hacer peticiones a API's de una manera más controlada, y no siempre dependiendo del servidor en producción.
Quiza puede ser de tu interés:
Top comments (3)
Me quedo más claro su uso gracias al post jejeje!
Saludos!
muchas gracias por leerlo y dejar tu comentario! a mi también me costo entenderlo xd
Excelente comentario para complementar un poco más lo ilustrado en el post @lukeshiru , es complicado encontrar casos de usos reales para este hook, y eso lo hace algo ambiguo. Saludos.