Componentes de React con TypeScript: Creación de Lazy Image
Resumen
¿Cómo se define un componente en React?
Iniciemos nuestra aventura por el fascinante mundo de React comenzando con lo más básico: la definición de un componente. Un componente es esencialmente una función que devuelve un resultado, comúnmente un elemento visual representado por JSX. En este caso, aprenderemos a definir un componente llamado RandomFox utilizando TypeScript, que es un superconjunto de JavaScript, proporcionando un sistema de tipos estático.
¿Qué extensión usamos para archivos TypeScript con JSX?
La extensión que utilizamos para combinar TypeScript y JSX es .tsx. Este formato nos permite escribir archivos de React con la sintaxis de JSX, manteniendo el tipado estático y las características de TypeScript. Esta extensión se convierte en nuestra herramienta principal al trabajar con componentes de React.
// Ejemplo básico de un componente en TypeScript con JSXimportReactfrom'react';exportconstRandomFox:React.FC=()=>{return<img src="imagen.jpg" alt="Imagen de un zorro aleatorio"/>;};
¿Cuáles son las formas de definir un componente en TypeScript y cuál es la recomendada?
Existen múltiples maneras de definir un componente en TypeScript, pero las más comunes son:
Forma Implícita: Se define una función que retorna JSX, sin especificar el tipo de retorno.
Forma Explícita (Recomendada): Se indica explícitamente que la función retorna un JSX.Element.
exportconstRandomFox=():JSX.Element=>{return<img src="imagen.jpg" alt="Imagen de un zorro aleatorio"/>;};
Con React.FC (Functional Component): Se emplea el tipo proporcionado por React.
Estas diferencias residen en cómo tipamos los retornos y las constantes. La forma recomendada actualmente es la segunda debido a que nos permite ser explícitos en nuestro código sin depender de funcionales adicionales que React empleaba anteriormente.
¿Cómo generar una imagen aleatoria?
Veamos cómo integrar una API para generar imágenes aleatorias. La idea es obtener imágenes de zorros aleatorios desde una API externa utilizando números aleatorios.
¿Cómo implementamos una función random en TypeScript?
Para lograr este comportamiento, se crea una función que genera un número aleatorio entre 1 y 123, ya que este es el rango disponible de imágenes en la API.
Utilizamos este número para completar la URL de la imagen.
¿Cómo asignamos la imagen aleatoria al componente?
Con nuestra función random lista, la integramos en el componente.
exportconstRandomFox=():JSX.Element=>{// Generamos el número aleatorioconst imageNumber =generateRandomNumber();// Construimos la URL de la imagenconst imageUrl =`https://randomfox.ca/images/${imageNumber}.jpg`;return(<img
src={imageUrl} alt="Imagen de un zorro aleatorio" width="320" className="rounded"/>);};
Al recargar el componente, la imagen cambiará debido al número aleatorio generado cada vez.
¿Cómo se integra el componente en un proyecto?
Finalmente, integramos este componente en un archivo principal del proyecto.
importReactfrom'react';import{RandomFox}from'./components/RandomFox';constApp=()=>(<div><h1>Mira un zorro aleatorio cada vez que recargues</h1><RandomFox/></div>);exportdefaultApp;
Inicie el desarrollo de sus componentes con TypeScript y React, disfrutando de la tipificación estática y descubra con alegría cómo las imágenes de zorros le dan un toque único a su aplicación. La innovación comienza con aprender, así que continúe explorando y potenciando sus habilidades.
En la función random, podríamos agregar que el tipo de dado que se regresa es un number:
const random =():number=>Math.floor(Math.random()*123)+1
Justo estaba pensando en ello
Diferentes formas de definir un componente
La forma en la que se trabajan los componentes en TypeScript con React es con la extensión .tsx. (archivos de TypeScript que incluyen JSX).
Hay distintas formas de definir un componente en React con TypeScript, veamos las 4 formas más comunes de hacer esto:
**// Forma implícito (JSX:Element)**constMyComponent=()=>{return(<div><h2>Hola!</h2></div>)}**// Forma explícita "JSX.Element"**constMyComponent=():JSX.Element=>{return(<div><h2>Hola!</h2></div>)}**// Usando tipos de React "FunctionComponent"**importtype{FunctionComponente}from"react"****constMyComponent:FunctionComponent=()=>{return(<div><h2>Hola!</h2></div>)}**// Usando tipos de React "FC"**importtype{FC}from"react"****constMyComponent:FC=()=>{return(<div><h2>Hola!</h2></div>)}
Hoy en día, el estándar que se manera comúnmente es la segunda manera Forma explícita "JSX.Element", este es el formato de que debemos utilizar.
Si tienen algun problema con las imagenes agreguen el dominio a su configuracion de nextjs
Gracias
Wow, me encantó el pull request que lo explica. Una de las desventajas es que provee una definición implícita de children, lo que significa que todos los componentes aceptan children, incluso si no deberían, lo que puede ser un error difícil de detectar. Además, React.FC no soporta genéricos, lo que puede limitar la capacidad de definir componentes reutilizables. No funciona correctamente con defaultProps.
Yo tuve un error al intentar tipar el componente de la forma mostrada en este curso, que era:
const component = (): JSX.Element => {} // Cannot find namespace 'JSX'
A esta manera:
const component = (): React.JSX.Element => {}
Y soluciono el error, dejo por si alguno le sirve
otra forma de solucionarlao es importar JSX asi
import{JSX}from"react";..
Y entonces si usarlo
Extensión para autocompletar clases con tailwind.css Tailwind CSS IntelliSense
Donde está la lectura sobre por qué no es la mejor idea utilizar Functional Components? no está en los recursos del nuevo frontend
El tipado de FunctionalComponent (FC) ha caído en desuso porque, aunque es una forma válida de definir componentes, no proporciona beneficios adicionales significativos en comparación con el uso de JSX.Element. Usar JSX.Element es más explícito y claro, ayudando a evitar confusiones en el código, especialmente en componentes complejos. Además, el uso de JSX.Element permite a TypeScript realizar mejor las inferencias de tipos, lo que facilita la detección de errores en tiempo de compilación. Esto se alinea con las mejores prácticas actuales en la comunidad de desarrollo de React y TypeScript.
No se si cuando se hizo el curso no existia pero, no que Next ya por defecto hace lazy loading en las imagenes?
¿Por qué en Next.js está todo en la raíz y no en una carpeta src 🤔?
El folder SRC es opcional y puede ser agregado en la configuración de next.
para gustos colores
Si alguien tuvo problemas con la pagina de imagenes Random como yo, en este link puede obtener imagenes de la nasa, solo se registran y les entregan un api-key, este lo ponen en cada query que hagan:
✅ Aquí estamos indicando explícitamente que la función retorna un JSX.Element.
🔍 Esto mejora la legibilidad, el autocompletado y la seguridad de tipos.
🟪 3. Usando FunctionComponent o FC
Otra opción es tipar directamente la constante del componente:
import type {FunctionComponent,FC}from'react';exportconstRandomFox:FunctionComponent=()=>{return<img />;};exportconstRandomFox:FC=()=>{return<img />;};
📌 FunctionComponent y FC son tipos proporcionados por React.
🧠 Importante:
Cuando importamos solo tipos, usamos import type
Esto permite que el compilador los elimine durante el build, optimizando el bundle 🚀
🔍 Comparación de las opciones
❌ Opción 1 (implícita):
No es recomendable, ya que depende solo de la inferencia.
⚠️ Opción 2 (JSX.Element):
Tipamos el retorno de la función. Clara y explícita ✅
⚠️ Opción 3 (FunctionComponent / FC):
Tipamos la constante del componente.
⭐ Recomendación actual
📌 Hoy en día, la opción más recomendada es usar:
():JSX.Element
✔️ Es más simple
✔️ Evita comportamientos implícitos (como children automáticos en FC)
✔️ Es más explícita y predecible
no se porque motivo me arroja este erorr
no tiene que ver con el codigo de la imagen, sino con la disposicion de carpetas dentro de tu proyecto, no se que version de next estes usando, pero aprende acerca de como funcionan las rutas por carpetas en nextjs
TENGO UNA DUDA EL CURSO AUN SERIA VALIDO AL DIA DE HOY SEPTIEMBRE 2025??
Me da un error de consola cuando intento renderizar la app...
diciendo que <head> no puede ser utilizado como child dentro de un <div> hay alguien mas que tenga ese error o alguien que me pueda explicar como solucionarlo, porfa ?
Alguien sabe cuál es la lectura de porque no se debe de usar FuntionComponent?