Contenido del curso
Tipado en React
React y el DOM
- 8

Manejadores de Eventos en React con TypeScript
16:48 min - 9

useRef con TypeScript sin errores de tipos
Viendo ahora - 10

Lazy loading con Intersection Observer en React
12:39 min - 11

Creación de Componentes Genéricos con TypeScript y Lazy Loading
15:09 min - 12

Implementación de onLazyLoad en React con TypeScript
04:04 min
Configuraciones avanzadas
Próximos pasos
useRef con TypeScript sin errores de tipos
Resumen
Trabajar con useRef en React y TypeScript parece sencillo hasta que aparece el primer error críptico de tipos. Si estás construyendo componentes que necesitan acceder a un nodo del DOM, como una imagen lazy, vas a necesitar este hook y entender por qué inicializarlo en null es la regla de oro.
¿Qué es useRef y para qué sirve en React?
useRef es el hook de React que te permite crear referencias a nodos del DOM y acceder a ellos en tiempo de ejecución. Es la pieza que te falta cuando necesitas que un componente sepa qué está pasando con un elemento real del navegador.
En el proyecto que venimos trabajando, el componente RandomFox era una imagen simple. Para volverlo lazy, necesitamos que sepa en qué momento entra al viewport, esa parte visible del navegador donde el usuario está mirando. Todo lo que está fuera del scroll no debería cargar todavía.
Para lograrlo, el plan combina tres piezas:
- Una referencia con useRef para apuntar al nodo de la imagen.
- Un observador de la Web API que detecte cuándo la imagen entra al viewport.
- useEffect para conectar el observador al ciclo de vida del componente.
¿Qué hace useRef en React? Crea una referencia mutable que apunta a un nodo del DOM o guarda un valor entre renders sin disparar re-renderizados.
¿Cómo se usa useRef sin TypeScript?
Si vienes de JavaScript puro, la implementación es directa. Importas el hook desde React, lo inicializas dentro del componente y lo asignas a la prop especial ref del elemento JSX.
jsx import { useRef } from 'react'
const node = useRef()
return <img ref={node} />
En tiempo de ejecución, esto funciona perfecto. El problema aparece cuando TypeScript entra en escena y empieza a quejarse de que algo no cuadra con los tipos [03:15].
¿Por qué TypeScript marca error al usar useRef?
TypeScript te dice que el tipo es un MutableRefObject que está como undefined, y que ese undefined no es asignable a HTMLImageElement. El error es largo y críptico, pero hay un truco para leerlo: siempre pregúntale a TypeScript por qué.
Vas bajando capa por capa:
- El tipo no es asignable. ¿Por qué?
- Porque las propiedades de
currentson incompatibles. ¿Por qué? - Porque
undefinedno es asignable aHTMLImageElement | null.
En esa última línea aparecen las tres pistas que necesitas: undefined, null y HTMLImageElement. Esa es la clave para resolverlo.
¿Cómo tipar useRef correctamente con TypeScript?
useRef acepta un genérico que le indica qué tipo de elemento del DOM vas a referenciar. Si no le pasas nada, los tipos de React asumen undefined por defecto, y de ahí viene el error.
La primera regla es ser explícito con el genérico. Como estamos trabajando con una imagen, el tipo correcto es HTMLImageElement:
tsx const node = useRef<HTMLImageElement>()
Pero TypeScript todavía no queda contento. Sigue diciendo que undefined no es compatible con HTMLImageElement | null. Aquí entra la segunda regla, y es una de las rarezas de React con TypeScript.
¿Por qué useRef debe inicializarse en null? Porque los tipos de React esperan
HTMLImageElement | null, yundefinedno es lo mismo quenullen el sistema de tipos, aunque ambos sean valores falsy en JavaScript.
La solución final pasa el valor inicial explícitamente:
tsx const node = useRef<HTMLImageElement>(null)
return <img ref={node} />
¿Cuál es la diferencia entre null y undefined en TypeScript?
En JavaScript, null y undefined se comportan parecido en condicionales, pero TypeScript los trata como tipos distintos. Cuando no inicializas el argumento de useRef, JavaScript lo pasa como undefined, y eso choca con el tipo que espera el hook.
Por eso la regla de oro al usar useRef en React con TypeScript es doble:
- Pasa siempre el genérico con el tipo del elemento del DOM, lo más específico posible.
- Inicializa el valor en
nullcuando aún no tienes el nodo disponible.
No es algo que adivinarías leyendo la documentación rápido. Es uno de esos pequeños trucos que aparecen al combinar React con TypeScript, y entenderlo te ahorra horas de pelear con errores incomprensibles.
¿Qué cambia visualmente al agregar useRef al componente?
Nada. Y esa es la parte interesante. Al recargar el proyecto, la imagen se ve igual que antes. Lo que ganaste es acceso programático al nodo para usarlo en el siguiente paso, que es conectar el observador del viewport.
Como ya le dijiste a TypeScript que la referencia es de tipo HTMLImageElement, ahora puedes acceder a las propiedades específicas de una imagen del DOM con autocompletado correcto. Ese es el verdadero valor de tipar bien: el editor te ayuda en lugar de estorbarte.
El siguiente paso del proyecto es agregar la Web API de observables para detectar cuándo la imagen entra al viewport y dispararla solo en ese momento. ¿Cómo lo implementarías tú con IntersectionObserver y useEffect? Cuéntame en los comentarios qué enfoque usarías antes de ver la solución.