Piensa: ¿qué es lo más molesto de trabajar con Javascript? Todos los lenguajes de programación tienen bucles, condicionales, variables y operaciones lógicas; algunos tienen eventos, pero solo Javascript tiene el DOM. Sí, eso es lo más molesto al codificar para la web, no solo es muy lento en términos de rendimiento, sino que también hace que tu código sea redundante, engorroso y enorme.
Sólo mira este ejemplo: todas las líneas de código que necesitamos para crear un simple elemento HTML en nuestro DOM:
1var divElem = document.getElementById("myFirstDiv"); //Selecciona un elemento padre 2var myNewHOne = document.createElement("H1"); //Crea un nuevo elemento en el DOM 3var t = document.createTextNode("Hello World");// crea el contenido de un nuevo elemento 4myNewHOne.appendChild(t); //Añadir el contenido del texto al nuevo elemento 5divElem.appendChild(myNewHOne);// Añadir el nuevo elemento dentro del elemento padre 6 7Es bastante código ¿VERDAD?
¡El primer objetivo de React es arreglar eso!
React.js se define a sí mismo como una librería de front-end para interfaces de usuario (UIs). Básicamente, React propone una nueva forma de crear sitios web al rediseñar todo el flujo de trabajo de codificación y hacer que los sitios web sean más rápidos.
A partir de ahora, React.js se hará cargo del DOM; tu trabajo es crear tus propios <Tags>
y definir cómo deben mostrarse o representarse (render).
Dividirás tu aplicación en partes pequeñas (componentes), todas juntas forman el sitio web.
Todos tus nuevos <Components>
son una pequeña parte de tu diseño, pero algunos están ocultos al principio. Tendrás que mostrarlos y esconderlos según el comportamiento del usuario.
Hasta ahora, hemos concatenado strings para crear el HTML que queremos colocar en el innerHTML
de un elemento del DOM, por ejemplo:
1document.querySelector('body').innerHTML = '<h1>'+person.name+'</h1>';
React.js viene con JSX
, un "lenguaje" especial (una extensión de JS) que te permitirá escribir HTML puro dentro de tu código React/Javascript sin tener que usar comillas (convirtiéndolo en string). Básicamente elimina la apestosa necesidad de concatenar string HTML.
Si tienes que usar código JS dentro de tu bloque HTML, simplemente debes envolver el código entre llaves como lo hemos visto en ejemplos anteriores, parecido a cuando usamos para construir ${dynamic_code}
, como lo hemos visto en proyectos anteriores.
1return <h1 id="name"> {person.name} </h1>;
Recuerda, que en JSX/React el código dinámico JS dentro del código de HTML (como el anterior) siempre debe evaluarse como una expresión. Es por eso que no podemos usar declaraciones JS dentro de las llaves, como la declaración if..else por ejemplo. En su lugar debemos usar una expresión ternaria que tiene el mismo efecto.
1return <h1 id="name"> {if(person.name == "John") "John"; else "Tom" } </h1>; //no funciona en JSX 2 3return <h1 id="name"> {person.name == "John" ? "John" : "Tom" } </h1>; //funciona en JSX y evualará a <h1 id="name"> John </h1> o a <h1 id="name"> Tom </h1> dependiendo del valor de person.name
☝️ Familiarizate con las operaciones condicionales ternarias 🔗AQUÏ
☝️ Revisa las diferencias entre expresiones y declaraciones 🔗AQUÏ
¿Recuerdas los componentes de Bootstrap?
React lleva ese concepto más allá al dividir y encapsular todo tu sitio web en componentes más pequeños. Estos componentes se pueden basar en el uso de las estructuras JS familiares de función
o clase
.
Así es como declaramos un componente de React como una función, que es en lo que nos centraremos durante este curso:
1import React from 'react'; 2 3function MyComponent(){ 4 return ( 5 //Aquí debiese ir algún código HTML 6 ); 7} 8
Ahora digamos que queremos que este componente devuelva una Bootstrap card: cada vez que lo llamemos.
Así es como lo hacemos en una app React:
1import React from 'react'; 2 3//Renombramos el componente a MyCard 4 5function MyCard(){ 6 return ( 7 <div className="card" style={{width: "18rem"}}> //Observa que algunos atributos html cambian sus nombres o valores para funcionar en React 8 <img className="card-img-top" src="..." alt="Card image cap" /> //Ahora debemos tener cuidado de cerrar siempre las etiquetas de cierre automático 9 <div className="card-body"> 10 <h5 className="card-title">Card title</h5> 11 <p className="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p> 12 <a href="#" className="btn btn-primary">Go somewhere</a> 13 </div> 14 </div> 15 ); 16} 17
👆 Cada componente en React debe tener un método de renderizado que devuelva un bloque de código HTML.
Cada componente se puede renderizar llamando a su <tag>
, que se parece a las etiquetas HTML pero siempre comienza con una letra mayúscula. La diferencia es que ahora el nombre de la <tag>
es el nombre del componente React (p. ej.,
El componente anterior ahora renderizará (se mostrará en la página) una Bootstrap card en cualquier lugar donde llames a
1 <MyCard />
Por lo general, llamamos componentes dentro de la sección return de otro componente:
1import React from 'react'; 2 3function MyComponent(){ 4 return ( 5 <MyCard /> 6 ); 7} 8
El componente React más simple es solo una función que devuelve algo de HTML. También puedes declarar cualquier Componente de React como una clase. La nueva clase que declaras debe tener un método de renderizado que especifique cómo debe mostrarse el componente.
Aquí hay un ejemplo del mismo componente <MyCard />
, pero ahora declarado como una clase:
1import React from 'react'; 2 3//Aquí creamos el componente Modal como una clase. 4export class MyCard extends React.Component{ 5 6 render(){ 7 return ( 8 <div class="card" style="width: 18rem;"> 9 <img class="card-img-top" src="..." alt="Card image cap"> 10 <div class="card-body"> 11 <h5 class="card-title">Card title</h5> 12 <p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p> 13 <a href="#" class="btn btn-primary">Go somewhere</a> 14 </div> 15 </div> 16 ); 17 } 18}
☝️ Este es un componente de clase. Te recomendamos que uses componentes funcionales y hooks en su lugar ya que lo componentes de clase están considerados como legacy(deprecados).
Con React, toda la aplicación se considera un componente.
Lo primero que harás al crear grandes aplicaciones React es definir un gran componente, al que llamamos primario o principal. Contendrá toda tu aplicación.
Luego, debes inyectar este componente principal en el DOM del sitio web con el método ReactDOM.render(), así:
1import React from 'react'; // import obligtorio del react package 2import ReactDOM from 'react-dom'; //import obligtorio del react-dom package 3 4//creando nuestro componente React 5function MyMainComponent (){ 6 return <div>Hello World</div>; 7} 8 9 10ReactDOM.render(<MyMainComponent />, document.querySelector('#app')); 11// Está implícito que hay un contenedor div con el id 'app' en el cuerpo HTML de tu sitio web original 12// A través de <MyMainComponent /> toda tu aplicación react se insertará en esa ubicación del DOM 13
Debido a que <MyMainComponent />
en este ejemplo es el componente principal, todos los demás componentes de tu aplicación deberán ser llamados dentro de este componente principal o en sus descendientes (hijos, nietos, etc.). Cualquier componente que no se llame en el componente principal o dentro de sus descendientes nunca aparecerá en el DOM y, por lo tanto, no aparecerá en tu página web.
1function GrandchildComponent (){ 2 return " Hello, I'm the Grandchild "; 3} 4 5function ChildComponent (){ 6 return ( 7 <p> 8 <h3>Hello I'm the Child, and below is the Grandchild</h3> 9 <GrandchildComponent /> 10 </p> 11 ); 12} 13 14function RandomComponent (){ 15 return " Hello, I'm just a random component that will not be rendered =( "; 16} 17 18function MyMainComponent (){ 19 return <ChildComponent />; 20} 21 22 23ReactDOM.render(<MyMainComponent />, document.querySelector('#app')); 24
En este ejemplo, <ChildComponent />
y <GrandchildComponent />
terminarán en el DOM y se renderizarán porque se les llama dentro del componente principal o un descendiente. <RandomComponent />
Por otro lado, nunca se mostrará en la página porque no se llama de esa manera.
Un "Layout" o diseño en React es básicamente la combinación de dos o más componentes (llamados componentes propiamente tales) en un componente principal (llamado view o vista).
Por ejemplo:
Supongamos que tiene un sitio web de una página con tres secciones: Home
, About Us
y Contact Us
. La forma "React" de hacerlo será creando un componente de view o vista más grande que contiene cada componente (sección), así:
1 2export function EntireWebsiteLayout (){ 3 return ( 4 <div> 5 <Home /> 6 <AboutUs /> 7 <ContactUs /> 8 </div> 9 ); 10} 11//Está implícito que los componentes Home, AboutUs y ContactUs ya han sido definidos
☝️ Este es un componente de clase. Te recomendamos que uses componentes funcionales y hooks en su lugar ya que lo componentes de clase están considerados como legacy(deprecados).
Esos componentes que sirven para sostener el layout o diseño de tus páginas web, no se utilizarán para nada más, es lo que llamamos "views o vistas", y los típicos componentes que podemos reutilizar muchas veces con diferente input (como componente button o card) les llamaremos "components o componentes" dentro de las carpetas de nuestra aplicación.
Así es como React renderizará tu layout:
Cada componente tendrá método de renderizado. El documento HTML resultante, estará compuesto por la combinación de todos las salidas que todos los componentes tienen en sus métodos de renderizado. Échale un vistazo a la siguiente imagen para tener una idea.
En la estructura de tu aplicación, puedes tomar un destacador y comenzar a marcar todos los componentes que tendrá tu aplicación. Los más fáciles son los componentes típicos de Bootstrap: NavBar, Card, etc. También debieras definir tus propios componentes.
En este caso, hemos decidido crear los siguientes componentes basados en el sitio web de YouTube:
<VideoPlayer />
: Renderizará todo el reproductor de video con todos los <VideoControls />
dentro.<Description />
: Se renderizará la descripción del video.<Comments />
: Mostrará todos los comentarios y tendrá un grupo de <VideoCard />
: Mostrará una miniatura de video a la izquierda con una pequeña descripción a la derecha y llevará a las personas a esa página de video cuando se haga clic.<VideoTitle />
: Renderizará el titulo del video.Una vez que hayas terminado de identificar tus componentes, es hora de comenzar a programar. Crea una nueva clase de Javascript en un archivo separado para cada uno de esos componentes.
Cada clase debe tener una función llamada render. Esto devolverá el código HTML que el componente generará en el documento del sitio web.
Cada componente viene con un objeto global (compartido solo dentro del mismo Componente) que tiene el único propósito de almacenar los datos necesarios para representarlo. Por ejemplo, digamos que estoy desarrollando un componente de reloj que tiene que imprimir la hora actual cada segundo. Necesitaría la hora actual en el estado del componente ... el código se verá algo así:
👆 La siguiente demostración actualiza la hora actual en cada segundo:
Cualquier componente puede tener propiedades, al igual que en HTML. Por ejemplo, en HTML podríamos definir la propiedad src de una imagen como esta:
1<img src="http://myurl.com/path/to/image.png" />
En React, podemos establecer las propiedades de la misma manera y nuestros componentes podrán leerlas y mostrar diferentes cosas basadas en las props que se le están pasando.
1// Aquí podemos inventar una nueva propiedad 'textColor', pero ahora tendremos que asegurarnos de codificar su comportamiento 2<ClockComponent textColor="red" />
En el código anterior, hemos inventado una nueva propiedad para el ejemplo ClockComponent. Ahora tendremos que determinar y codificar cómo funcionará esa nueva propiedad dentro de nuestro componente. En este caso en particular, tendríamos que asignar style color rojo a la salida de texto del reloj, así:
Un componente real de alta calidad sólo debe comunicarse con otros componentes a través de sus propiedades. De esta manera podremos reutilizar ese componente muchas veces en el futuro (de manera similar a como funcionan las funciones y los parámetros).
Cada componente funciona como una mini aplicación. Puedes controlar y definir el flujo de trabajo de sus componentes en función de una serie de métodos disponibles que puede declarar y codificar de acuerdo con sus necesidades.
🔗 Aquí encontrarás una explicación más detallada de cada método de ciclo de vida disponible.