useRef
El hook useRef
en React es una herramienta poderosa que se utiliza principalmente para manipular referencias a elementos DOM o para almacenar valores mutables que no desencadenan renderizados adicionales cuando cambian.
¿Qué hace useRef
?
- Referencia al DOM: Permite acceder directamente a elementos del DOM sin necesidad de usar
document.querySelector
. - Almacenar valores mutables: Sirve para almacenar valores que persisten entre renderizados sin provocar re-renderizados cuando cambian.
- Persistencia de datos: Mantiene un valor persistente a través de los ciclos de vida del componente.
Estructura básica
const ref = useRef(initialValue);
initialValue
: Es el valor inicial de la referencia.ref.current
: Es el objeto mutable que contiene el valor de la referencia.
Casos de uso y ejemplos
1. Manipulación del DOM
El caso más común de useRef
es para acceder a elementos del DOM.
import React, { useRef } from "react";
function FocusInput() {
const inputRef = useRef();
const handleFocus = () => {
inputRef.current.focus(); // Accede al elemento DOM y enfoca el input
};
return (
<div>
<input ref={inputRef} type="text" placeholder="Escribe algo aquí..." />
<button onClick={handleFocus}>Enfocar input</button>
</div>
);
}
export default FocusInput;
Explicación:
inputRef.current
apunta al elementoinput
del DOM.- El botón activa la función
handleFocus
, que llama al métodofocus()
del input.
2. Almacenar valores mutables
useRef
es útil para guardar valores que no necesitan disparar un re-renderizado.
import React, { useRef, useState } from "react";
function ClickCounter() {
const countRef = useRef(0); // Estado mutable
const [renderCount, setRenderCount] = useState(0); // Estado que renderiza
const increment = () => {
countRef.current += 1; // Cambia el valor, pero no causa re-render
console.log(`Clicks: ${countRef.current}`);
};
const forceRender = () => {
setRenderCount(renderCount + 1); // Fuerza un re-render
};
return (
<div>
<p>Clicks guardados en ref: {countRef.current}</p>
<p>Clicks mostrados en estado: {renderCount}</p>
<button onClick={increment}>Incrementar ref</button>
<button onClick={forceRender}>Forzar re-render</button>
</div>
);
}
export default ClickCounter;
Explicación:
countRef
guarda un valor que no causa re-renderizados.- Si necesitas mostrar el valor actualizado en la interfaz, puedes usar
forceRender
.
3. Persistencia de valores entre renderizados
useRef
puede almacenar valores que persisten a través de renderizados.
import React, { useRef, useEffect, useState } from "react";
function Timer() {
const timerRef = useRef(null); // Guardará la referencia al temporizador
const [seconds, setSeconds] = useState(0);
useEffect(() => {
timerRef.current = setInterval(() => {
setSeconds((prev) => prev + 1);
}, 1000);
return () => {
clearInterval(timerRef.current); // Limpia el temporizador al desmontar
};
}, []);
return <p>Segundos: {seconds}</p>;
}
export default Timer;
Explicación:
timerRef
guarda el ID del temporizador (setInterval
).- Esto permite acceder al temporizador para detenerlo en la función de limpieza.
4. Comparar valores previos
Puedes usar useRef
para guardar el valor previo de una variable.
import React, { useRef, useState, useEffect } from "react";
function PreviousValue() {
const [count, setCount] = useState(0);
const prevCount = useRef();
useEffect(() => {
prevCount.current = count; // Guarda el valor actual antes de que cambie
}, [count]);
return (
<div>
<p>Valor actual: {count}</p>
<p>Valor previo: {prevCount.current}</p>
<button onClick={() => setCount(count + 1)}>Incrementar</button>
</div>
);
}
export default PreviousValue;
Explicación:
prevCount
almacena el valor decount
antes de que este cambie.- Es útil para comparar estados actuales y previos.
Diferencias con useState
Característica | useRef | useState |
---|---|---|
Provoca re-renderizados | ❌ No | ✅ Sí |
Persistencia | ✅ Entre renderizados | ✅ Entre renderizados |
Uso típico | Referencias DOM, valores mutables | Manejo de estados que afectan la UI |
Consideraciones importantes
- No provoca re-renderizados: Cambiar
ref.current
no actualiza la UI. Si necesitas que la UI cambie, usauseState
. - Ideal para valores mutables:
useRef
es perfecto para valores que cambian frecuentemente pero no necesitan reflejarse en la interfaz. - Acceso al DOM: Es el método recomendado para interactuar con el DOM directamente en componentes funcionales.