Introducción a React: ¿Qué es y por qué aprenderlo?
React es una de las librerias mas populares de JavaScript para el desarrollo de aplicaciones móviles y web.
Introducción
React es una librería creada por facebook, y se puede utilizar para la componetizacion y reutilización de elementos una página web. React tiene ciertas caracteristicas que la hacen destacar sobre otras librerías de JavaScript.
Virtual DOM
Primero debemos saber ¿Qué es el DOM? El DOM, (Document Object Model o Modelo de Objetos del Documento, en español) es una API definida para representar e interactuar con cualquier documetno HTML o XML. En palabras mas sencillas, el DOM es un modelo del documento que se esta cargando en el navegador, y representa el documento como un árbol de nodos, y cada nodo representa una parte del documento, sea un elemento, una cadena de texto o un comentario.
Entonces, ¿Que es el virtual DOM? El Virtual DOM, o VDOM, es un árbol de nodos virtual que React crea mientras estamos haciendo el trabajo. React almacena arboles virtuales en la memoria, al hacerlo, puedes decirle a react que actualice una parte especifica lo que hace mas rapido la renderización en el DOM real.
Cuando un desarrollador React realiza un cambio en una app, react compara y solo toma en cuenta los nodos del arbol que fueron modificados y eso es lo que trae al DOM real.
JSX
JSX es una sintaxis de react donde en un mismo archivo podemos incluir elementos HTML y objetos JavaScript, es utilizada para la creacion de elementos en react. Ya que JSX acepta expresiones válidas de JavaScript y la incrustacion de funciones puede simplificar la estructura de código complejos.
Veamos un ejemplo:
const header = () => {
return (
<div>
<h1>Hola mundo</h1>
<p>Este es un ejemplo de JSX</p>
</div>
)
}
En el ejemplo anterior vemos la sentencia JSX, donde un componente está formado por una funcion flecha que retorna elementos HTML.
Cada componente de react debe tener un solo y unico elemento padre, y multiples componentes hijos.
Componetes y props
React divide la UI (user interface) en piezas aisladas y reutilizables de códigos llamadas componentes. Los componentes de React funcionan similar a las funciones de JavaScript ya que reciben entradas arbitrarias llamadas props
Props son la informacion que le pasamos a una equiqueta JSX.
Por ejemplo; className, _src, alt, width, y height son algunos de los props que puedes pasar a una etiqueta <img>
.
Aprendamos a pasar props.
Para este ejercicio utilizaremos el PlayGround que colocamos al final de este post, puedes ir copiando y pegando los codigos en cada paso para que veas los cambions y sepas como funciona.
Paso 0
Antes de comenzar, primero necesitamos saber qué se requiere para ejecutar React Primero necesitamos un Editor de Codigo, esta vez usaremos el editor online de CodePen, tambien necesitamos un compilador de JSX, para este caso utilizaremos babel, y dentro de nuestro archivo JS importaremos React y ReactDOM
import React from "https://esm.sh/react@18.2.0";
import ReactDOM from "https://esm.sh/react-dom@18.2.0";
Tambien necesitaremos una funcion que renderice el componente principal <App/>
en nuestro DOM.
ReactDOM.render(<App />, document.getElementById("root"));
Paso 1: Creemos nuestro primer componente
Vamos a crear un componente <Avatar/>
y ese componente lo colocaremos en nuestro componente <App/>
de esta manera
import React from "https://esm.sh/react@18.2.0";
import ReactDOM from "https://esm.sh/react-dom@18.2.0";
const Avatar = () => {
return (
<img
className="avatar"
src="https://i.imgur.com/1bX5QH6.jpg"
alt="Lin Lanying"
width={100}
height={100}
/>
);
};
const App = () => {
return (
<Avatar/>
);
};
ReactDOM.render(<App />, document.getElementById("root"));
Paso 2: Pasando props.
En este codigo, nuestro componente <App/>
no le está pasando ningun prop a su componente hijo <Avatar/>
.
const App = () => {
return (
<Avatar/>
);
};
Vamos a solucionar eso.
Para este ejemplo le pasaremos dos props: “person” (object) contiene dos valores y “size” (number) que sera el tamaño de la imagen.
import React from "https://esm.sh/react@18.2.0";
import ReactDOM from "https://esm.sh/react-dom@18.2.0";
const Avatar = () => {
return (
<img
className="avatar"
src="https://i.imgur.com/1bX5QH6.jpg"
alt="Lin Lanying"
width={100}
height={100}
/>
);
};
const App = () => {
return (
<Avatar
person={{ name: 'Lin Lanying', imageId: '1bX5QH6' }}
size={100}
/>
);
};
ReactDOM.render(<App />, document.getElementById("root"));
Paso 3: Recibiendo props en el componente hijo
En este paso construiremos una funcion que nos ayudará a crear las url de las imagenes de cada avatar
const getImageUrl = (person, size = 's') => {
return (
'https://i.imgur.com/' +
person.imageId +
size +
'.jpg'
);
}
Y esta función la usaremos en el componente <Avatar/>
, de esta manera:
const Avatar = ({person, size}) => {
return (
<img
className="avatar"
src={getImageUrl(person)}
alt="Lin Lanying"
width={100}
height={100}
/>
);
};
Quedando el codigo completo de esta manera
import React from "https://esm.sh/react@18.2.0";
import ReactDOM from "https://esm.sh/react-dom@18.2.0";
const getImageUrl = (person, size = 's') => {
return (
'https://i.imgur.com/' +
person.imageId +
size +
'.jpg'
);
}
const Avatar = ({person, size}) => {
return (
<img
className="avatar"
src={getImageUrl(person)}
alt="Lin Lanying"
width={100}
height={100}
/>
);
};
const App = () => {
return (
<Avatar
person={{ name: 'Lin Lanying', imageId: '1bX5QH6' }}
size={100}
/>
);
};
ReactDOM.render(<App />, document.getElementById("root"));
Paso 4: Creemos un valor predeterminado para size
Si el componente hijo no recibe ningun prop para size
, el valor predeterminado lo estableceremos en 100
, de esta manera:
...
const Avatar = ({person, size = 100}) => {
// El resto de la funcion
}
...
Quedando de esta manera
import React from "https://esm.sh/react@18.2.0";
import ReactDOM from "https://esm.sh/react-dom@18.2.0";
const getImageUrl = (person, size = 's') => {
return (
'https://i.imgur.com/' +
person.imageId +
size +
'.jpg'
);
}
const Avatar = ({person, size=100}) => {
return (
<img
className="avatar"
src={getImageUrl(person)}
alt="Lin Lanying"
width={size}
height={100}
/>
);
};
const App = () => {
return (
<Avatar
person={{ name: 'Lin Lanying', imageId: '1bX5QH6' }}
size={100}
/>
);
};
ReactDOM.render(<App />, document.getElementById("root"));
Ahora podemos reutlizar nuestro componente <Avatar/>
en cualquier lugar del codigo y las veces que sea necesario (reutilizable).
import React from "https://esm.sh/react@18.2.0";
import ReactDOM from "https://esm.sh/react-dom@18.2.0";
const getImageUrl = (person, size = 's') => {
return (
'https://i.imgur.com/' +
person.imageId +
size +
'.jpg'
);
}
const Avatar = ({person, size=100}) => {
return (
<img
className="avatar"
src={getImageUrl(person)}
alt="Lin Lanying"
width={size}
height={size}
/>
);
};
const App = () => {
return (
<div>
<Avatar
size={100}
person={{
name: 'Katsuko Saruhashi',
imageId: 'YfeOqp2'
}}
/>
<Avatar
size={80}
person={{
name: 'Aklilu Lemma',
imageId: 'OKS67lh'
}}
/>
<Avatar
size={50}
person={{
name: 'Lin Lanying',
imageId: '1bX5QH6'
}}
/>
</div>
);
};
ReactDOM.render(<App />, document.getElementById("root"));
Paso 5: añadamos un poco de estilo
Primero borraremos todos los componentes <Avatar/>
Para crear un componente <Card/>
que contendrá un div contenedor y renderizará el componente <Avatar/>
como children
const Card = ({children}) => {
return(
<div className="card">
{children}
</div>
)
}
y añadimos estilos
.app{
display: flex;
gap: 10px
}
.avatar {
border-radius: 100%;
}
.card {
background-color: transparent;
width: 150px;
display: flex;
flex-direction: column;
align-items: center;
border: solid 1px gray;
border-radius: 15px;
padding: 25px 10px;
}
Y todo nuestro codigo React quedará de esta manera:
import React from "https://esm.sh/react@18.2.0";
import ReactDOM from "https://esm.sh/react-dom@18.2.0";
const getImageUrl = (person, size = "s") => {
return "https://i.imgur.com/" + person.imageId + size + ".jpg";
};
const Avatar = ({ person, size = 100 }) => {
return (
<>
<img
className="avatar"
src={getImageUrl(person)}
alt={person.name}
width={size}
height={size}
/>
<p>{person.name}</p>
</>
);
};
const Card = ({ children }) => {
return <div className="card">{children}</div>;
};
const App = () => {
return (
<div className="app">
<Card>
<Avatar
size={80}
person={{
name: "Katsuko Saruhashi",
imageId: "YfeOqp2"
}}
/>
</Card>
<Card>
<Avatar
size={80}
person={{
name: "Aklilu Lemma",
imageId: "OKS67lh"
}}
/>
</Card>
<Card>
<Avatar
size={80}
person={{
name: "Lin Lanying",
imageId: "1bX5QH6"
}}
/>
</Card>
</div>
);
};
ReactDOM.render(<App />, document.getElementById("root"));
Inténtalo aqui debajo y mira los cambios.
PlayGround
See the Pen Saburo.js-React-PlayGround by MIguel José (@borgesmj) on CodePen.
Fuentes: