En React existen dos formas principales de crear componentes: los componentes de clases y los componentes funcionales. Aunque se pueden utilizar ambos, en la actualidad en el ecosistema de React se prefieren los componentes funcionales porque son mucho más sencillos y directos.
Ejemplos de componentes
Vamos a ver un ejemplo de componente muy sencillo utilizando ambas modalidades. Sin embargo, ten en cuenta que en el resto del tutorial vamos a utilizar los componentes funcionales, ya que son los que se han establecido como estándar en el ecosistema de React.
Aquí tienes un componente funcional. Se basa en construir una función, escribir su lógica en el interior (bucles, funciones, variables, etc...) y devolver un código JSX, que se utilizará para construir el HTML del componente:
function component() {
const name = "Manz";
return <h1>¡Hola, {name}!</h1>;
}
Ten en cuenta que en JSX se utiliza la sintaxis {variable}
y no la sintaxis ${variable}
que es la que se usa en los
En el caso de los componentes de clase, observa que creamos una clase que extiende de Component
o de React.Component
, una clase base de React. Luego, creamos un método render()
que es el que se ejecuta automáticamente para generar el HTML del componente:
class Component extends Component {
render() {
const name = "Manz";
return <h1>¡Hola, {name}!</h1>;
}
}
En él, devolvemos el código JSX que buscamos. Este tipo de componentes aunque son mucho más potentes y versátiles, se pueden complicar dependiendo de la destreza del programador.
Por esta razón, en el ecosistema de React se ha preferido apostar por los componentes funcionales, un modelo que reduce la barrera de conocimientos necesaria por parte del desarrollador, de modo que se puedan crear con una simple función.
Composición
Un aspecto fundamental en la programación es la composición. En React, es muy habitual utilizarla, de modo que debemos crear funciones (componentes) que se encarguen de funcionalidades específicas y si necesitamos realizar otras funcionalidades, creamos otro componente y el primero utiliza este último.
Hemos creado la función WelcomeUser
y la hemos colocado en otro fichero .jsx
con dicho nombre. Desde nuestro App.jsx
podemos importarla y utilizarla como si fuera una etiqueta HTML. De esta forma podemos reutilizar o usar componentes en otros componentes:
import { WelcomeUser } from "./WelcomeUser.jsx";
export function App() {
const title = `Mi Aplicación`;
return (
<>
<h1>{title}</h1>
<WelcomeUser />
</>
);
}
/* WelcomeUser.jsx */
export function WelcomeUser() {
const user = "Manz";
return <h2>¡Hola, {user}!</h2>;
}
Simplemente, la función WelcomeUser
la movemos a otro fichero .jsx
y le añadimos la palabra clave export
al principio. De esta forma lo tendremos todo mejor organizado. Algunas consideraciones importantes:
- 1️⃣ Crea siempre tus ficheros de React con extensiones
.jsx
y no.js
. - 2️⃣ Aunque puedes usar
export default
, las exportaciones nombradas suelen ser más intuitivas. - 3️⃣ En general, se intenta que las funciones tengan nombres compuestos y en PascalCase.
- 4️⃣ Como puedes ver, en React puedes «autocerrar» los componentes.
Lo ideal es siempre separar con Módulos ESM las funciones en ficheros
.jsx
diferentes.
Condicionales
A medida que vamos creando componentes, será muy habitual que necesitemos mostrar un contenido u otro dependiendo de ciertas condiciones. En React esto es muy sencillo de realizar. Imaginemos el siguiente código donde queremos mostrar un mensaje de bienvenida si el usuario está logueado o no en la web:
- El componente
WelcomeUser
es una función que saluda al usuario logueado. - El componente
UnknownUser
es una función que te indica que puedes registrarte en la página.
import { WelcomeUser } from "./WelcomeUser.jsx";
import { UnknownUser } from "./UnknownUser.jsx";
export function App() {
const title = `Mi Aplicación`;
const userLogged = true;
const welcomeMessage = userLogged ? <WelcomeUser /> : <UnknownUser />;
return (
<>
<h1>{title}</h1>
{welcomeMessage}
</>
);
}
Observa que la constante userLogged
es la que nos indica si el usuario está identificado. Ahora mismo es un simple
En lugar de utilizar un operador ternario podemos utilizar un
if
tradicional, o incluso añadir el ternario en el JSX. Eso si, intenta siempre mantenerlo legible y usar la opción que se vea más sencilla.
Manejando datos
La estructura funcional que tiene React hace ideal trabajar con datos, ya que al separar la lógica (Javascript) del renderizado (JSX), hace mucho más sencillo manipular y modificar la información.
Observa el siguiente ejemplo donde, a partir de un
export function App() {
const title = `Lista de usuarios`;
const data = [
{ id: 42, name: "ManzDev", role: "Streamer" },
{ id: 56, name: "Felix", role: "Pole Winner" },
{ id: 666, name: "Kevin", role: "Banned user" },
{ id: 45, name: "Blur", role: "BanHammer" }
];
return (
<>
<h1>{title}</h1>
<hr />
<ul>
{data.map(user => (<li key={user.id}>{user.name} ({user.role})</li>))}
</ul>
</>
);
}
En React es muy común utilizar el método .map()
para transformar un array de datos en una estructura HTML que utilizaremos en nuestra parte JSX del componente. Recuerda que si el componente se va complicando, lo ideal es separar en varios componentes. Hazlo siempre que puedas reutilizar partes o quieras simplificar código y evitar que se complique.
Dos detalles importantes antes de terminar:
1️⃣ Ahora mismo los datos están definidos dentro del componente. En React, esto no es lo habitual, sino que se suele crear un estado. En próximos temas profundizaremos en esto.
2️⃣ Observa que en cada elemento
<li>
generado, hemos aplicado un atributokey
con el ID del usuario. Esto es una buena práctica en React para optimizar la renderización de los componentes. En este ejemplo no es útil porque la lista es estática y no cambia, pero si lo hiciera, React podría diferenciar un elemento de otro por sukey
y podría optimizar la lista para alterarla de forma eficiente. Hablaremos de ello más adelante.