Curso react nivel medio
Introducción
useRef es un hook en React que te permite crear una referencia mutable que puede usarse para acceder directamente a un elemento DOM o almacenar un valor que persiste entre renderizaciones sin causar renderizados adicionales.
¿Qué es useRef?
-
Referencia a elementos DOM:
Se usa comúnmente para acceder a nodos del DOM de manera directa, como inputs o botones. -
Valores persistentes:
También se puede usar para almacenar valores que no deben disparar renderizaciones cuando cambian (a diferencia deuseState).
Sintaxis
1const ref = useRef(valorInicial);
ref.current: Contiene el valor referenciado.valorInicial: Opcional, el valor inicial de la referencia.
Caso 1: Acceso a Elementos DOM
Ejemplo: Foco en un Input
1import React, { useRef } from "react"; 2 3function FocoInput() { 4 const inputRef = useRef(null); 5 6 const manejarFoco = () => { 7 inputRef.current.focus(); // Enfocar el input 8 }; 9 10 return ( 11 <div> 12 <input type="text" ref={inputRef} placeholder="Escribe algo..." /> 13 <button onClick={manejarFoco}>Enfocar Input</button> 14 </div> 15 ); 16} 17 18export default FocoInput;
Explicación
useRef: Crea una referencia para el input.inputRef.current: Proporciona acceso al nodo DOM del input.focus(): Enfoca el input al hacer clic en el botón.
Caso 2: Valores Persistentes entre Renderizados
useRef se puede usar para guardar valores que no deberían reiniciarse en cada render, como un contador.
Ejemplo: Contador Sin Renderizado
1import React, { useRef, useState } from "react"; 2 3function ContadorConRef() { 4 const contador = useRef(0); 5 const [estado, setEstado] = useState(false); // Estado para simular un render 6 7 const incrementar = () => { 8 contador.current += 1; // Incrementar el valor 9 console.log(`Contador actual: ${contador.current}`); 10 }; 11 12 return ( 13 <div> 14 <p>El contador actual es: {contador.current}</p> 15 <button onClick={incrementar}>Incrementar</button> 16 <button onClick={() => setEstado(!estado)}>Forzar Renderizado</button> 17 </div> 18 ); 19} 20 21export default ContadorConRef;
Explicación
contador.current: Persiste su valor entre renderizados.- Sin re-renderizado: Actualizar
contador.currentno causa que el componente se renderice. - Estado adicional: El botón "Forzar Renderizado" se usa para demostrar que el valor de
contador.currentno se pierde.
Diferencia Entre useState y useRef
| Característica | useState | useRef |
|---|---|---|
| Renderiza al cambiar | Sí | No |
| Persistencia de valores | Entre renderizados | Entre renderizados |
| Uso principal | Manejar datos que afectan la UI | Acceso a nodos DOM o datos que no afectan la UI |
Caso 3: Contar Renderizados
Ejemplo: Contador de Renderizados
1import React, { useRef, useEffect, useState } from "react"; 2 3function ContadorDeRenderizados() { 4 const renderCount = useRef(0); 5 const [contador, setContador] = useState(0); 6 7 useEffect(() => { 8 renderCount.current += 1; 9 }); 10 11 return ( 12 <div> 13 <p>El componente se ha renderizado: {renderCount.current} veces</p> 14 <button onClick={() => setContador(contador + 1)}>Incrementar</button> 15 </div> 16 ); 17} 18 19export default ContadorDeRenderizados;
Explicación
renderCount.current: Se incrementa en cada renderización.- Persistencia: El valor se mantiene entre renderizados sin afectar la UI.
Caso 4: Almacenar Valores Previos
Puedes usar useRef para guardar el valor anterior de una variable.
Ejemplo: Valor Previo
1import React, { useRef, useEffect, useState } from "react"; 2 3function ValorPrevio() { 4 const [contador, setContador] = useState(0); 5 const valorPrevio = useRef(null); 6 7 useEffect(() => { 8 valorPrevio.current = contador; 9 }, [contador]); 10 11 return ( 12 <div> 13 <p>Valor actual: {contador}</p> 14 <p>Valor previo: {valorPrevio.current}</p> 15 <button onClick={() => setContador(contador + 1)}>Incrementar</button> 16 </div> 17 ); 18} 19 20export default ValorPrevio;
Explicación
valorPrevio.current: Guarda el valor anterior decontador.useEffect: Actualiza el valor previo cada vez quecontadorcambia.
Caso 5: Integración con Bibliotecas Externas
Si necesitas interactuar con elementos DOM mediante bibliotecas externas (como animaciones o mapas), useRef es ideal.
Ejemplo: Animación con GSAP
1import React, { useRef, useEffect } from "react"; 2import { gsap } from "gsap"; 3 4function AnimacionConRef() { 5 const cajaRef = useRef(null); 6 7 useEffect(() => { 8 gsap.to(cajaRef.current, { x: 200, duration: 2 }); 9 }, []); 10 11 return <div ref={cajaRef} style={cajaEstilo}>¡Muevo con GSAP!</div>; 12} 13 14const cajaEstilo = { 15 width: "100px", 16 height: "100px", 17 backgroundColor: "blue", 18 color: "white", 19 display: "flex", 20 justifyContent: "center", 21 alignItems: "center", 22}; 23 24export default AnimacionConRef;
Explicación
cajaRef.current: Apunta al nodo DOM.- GSAP: Realiza la animación directamente en el elemento referenciado.
Consideraciones Importantes
-
No Causa Renderizaciones:
Actualizar un valor enuseRefno actualiza la UI. Para eso, usauseState. -
Acceso al DOM:
Úsalo para tareas relacionadas con nodos DOM, como enfocar inputs, medir tamaños o manejar integraciones con bibliotecas externas. -
Valores Persistentes:
Ideal para guardar datos entre renderizaciones sin causar re-renderizados.
Cuándo Usar ref en Formularios en Lugar de state
En React, los formularios generalmente se manejan con estado controlado (state), lo que significa que el valor de los inputs se sincroniza con el estado del componente. Sin embargo, hay casos en los que puede ser mejor usar referencias (ref), que permiten acceder directamente al valor del DOM sin actualizar el estado.
Cuándo Usar ref en Lugar de state
Casos Comunes:
-
Formularios simples con datos que no necesitan validación o manipulación previa:
Si solo necesitas leer el valor una vez al enviar el formulario,refpuede ser más eficiente. -
Optimización del rendimiento:
Si tienes formularios complejos con muchos campos y no quieres que cada cambio dispare una renderización, es mejor usarref. -
Integración con bibliotecas externas:
Cuando necesitas interactuar directamente con un elemento DOM, como un componente de terceros que no es compatible con React.
Ejemplo: Usando ref en un Formulario
Supongamos que tenemos un formulario que solo captura el nombre de usuario al enviarlo, pero no necesitamos que los cambios en el input disparen re-renderizaciones.
Código
1import React, { useRef } from "react"; 2 3function FormularioConRef() { 4 const inputRef = useRef(null); 5 6 const manejarEnvio = (e) => { 7 e.preventDefault(); 8 const valor = inputRef.current.value; 9 alert(`El nombre ingresado es: ${valor}`); 10 inputRef.current.value = ""; // Limpia el campo 11 }; 12 13 return ( 14 <form onSubmit={manejarEnvio}> 15 <label> 16 Nombre: 17 <input type="text" ref={inputRef} placeholder="Escribe tu nombre" /> 18 </label> 19 <button type="submit">Enviar</button> 20 </form> 21 ); 22} 23 24export default FormularioConRef;
Conclusión
useRef es un hook versátil que puede ser útil para:
- Acceder y manipular elementos DOM directamente.
- Guardar valores que persisten entre renderizados sin afectar la UI.
- Trabajar con bibliotecas externas que requieren manipulación directa del DOM.