Empezando con React, parte 1
Mi intención con esta serie de posts que voy a realizar es establecer un path de estudio desde 0 con React, si bien hay muchos cursos allá afuera bastante completos, estos posts los hago con la intención de interiorizar un poco mas el conocimiento que ya tengo y de paso, que sirva como guía para los que están iniciando con este framework, aclaro que vale mucho la pena revisar la documentación de React (también está en español), es bastante completa, sin más, empecemos.
Indice
Fundamentos
React se basa, al igual que muchos otros frameworks hoy en día, en el concepto de componentes.
Un componente es una pieza de código que puede ser reutilizada cuantas veces sea necesario, incluso entre proyectos (depende de como se escriba), esto permite reducir considerablemente la cantidad de código y sigue el principio DRY (dont repeat yourself). Veamos un ejemplo simple:
function NewButton (props) {
// Se retorna un nuevo elemento del DOM
return <button type="button">{props.label}</button>;
}
// Renderiza el componente
ReactDOM.render(<NewButton label="Save" />, document.getElementById("app"))
Vemos dos elementos clave acá, una función en JavaScript plano que retorna un elemento del DOM, en este caso un botón, vemos una propiedad "props.label" que es básicamente un valor que se le pasa a ese componente y vemos también algo llamado ReactDOM.render, que es la forma en como React renderiza nuestro componente en una posición que nosotros establecemos, en este caso esa posición sería en el nodo "app".
Las páginas que hacemos con React se llaman SPA (Single page application), mas adelante ahondaré en este concepto y en las diversas formas en las que podemos usar React para crear diferentes tipos de aplicaciones.
Con React, evitamos interactuar directamente con el api del DOM, React lo hace por nosotros, podría decirse que es como un intermediario, esto se hace para poder tener un buen rendimiento al hacer modificaciones en esos elementos del DOM que queremos cambiar, en otras palabras, no interactuamos directamente con esos elementos del DOM si no con elementos de React (React elements).
Recordemos que es el DOM y que es el Api del DOM.
Elementos del DOM
React usa una función llamada createElement para representar un elemento del DOM, ejemplo:
React.createElement("h2", {id: "subtitle"}, "Subtitulo de la página")
El primer argumento define el tipo de elemento, el segundo las propiedades, en este caso el Id sería "subtitle", y el tercer argumento representa el hijo del elemento, puede ser un nodo cualquiera envuelto entre <>, en este caso es solo el texto "subtitulo de la página".
Al renderizar React mostrará:
<h2 id="subtitle">subtitulo de la página</h2>
Como vemos, las propiedades son adicionadas como atributos, el hijo, es agregado como texto plano dentro del elemento, básicamente, un elemento de React es un literal de JavaScript que le dice a React como construir un elemento del DOM, si hacemos un console.log al elemento, veríamos algo como esto:
{
$$typeof: Symbol(React.element),
"type": "h2",
"key": null,
"ref": null,
"props": {id: "subtitle", children: "subtitulo de la página"},
"_owner": null,
"_store": {}
}
En este caso, el type le dice a React que tipo de elemento es, HTML o un SVG, props contiene los datos y los nodos hijos que van a ser construidos, la propiedad children se usa para mostrar otros nodos anidados como texto en este caso.
ReactDOM
Una vez el elemento ha sido generado, ReactDOM contiene lo necesario para poder renderizar ese elemento en el navegador, esto lo hacemos usando ReactDOM.render, para poder renderizar el elemento, necesitamos 2 argumentos, el elemento a renderizar como primer argumento y en donde lo vamos a renderizar como segundo argumento.
const subtitle = React.createElement("h2", null, "subtitulo de la página");
ReactDOM.render(subtitle, document.getElementById("app"));
Al renderizar, quedaría algo como lo siguiente:
<body>
<div id="app">
<h2>subtitulo de la página</h2>
</div>
</body>
Para renderizar elementos internamente, React usa los props.children, en este ejemplo, el texto que renderiza subtitulo de la página, que es hijo del elemento h2, sería nuestro children, pero estos children no son solo un elemento, son un arbol de elementos (element tree) que contiene un elemento padre y de ahí en adelante crece. Por ejemplo para renderizar una lista sería algo como esto:
<ul>
<li>Elemento 1</li>
<li>Elemento 2</li>
<li>Elemento 3</li>
</ul>
React.createElement("ul", null,
React.createElement("li", null, "Elemento 1"),
React.createElement("li", null, "Elemento 2"),
React.createElement("li", null, "Elemento 3"),
);
Vemos el nodo principal ul y los hijos, que serían los li.
Agregando clases a un elemento
Class es una palabra reservada de JavaScript, por eso React usa className para recibir los nombres de las clases en un componente, ejemplo:
React.createElement("ul", {className: "elements"},
React.createElement("li", null, "Elemento 1"),
React.createElement("li", null, "Elemento 2"),
React.createElement("li", null, "Elemento 3"),
);
Ya renderizado quedaría algo como esto:
<ul class="elements">
<li>Elemento 1</li>
<li>Elemento 2</li>
<li>Elemento 3</li>
</ul>
En este punto al ver el código es posible que esté confundido/a, ya que se ve diferente al código usualmente usado con React, mas complejo y tortuoso, bueno, el código que he puesto en los ejemplos es el que maneja React directamente, pero para facilitarnos la vida vamos a trabajar con JSX, JSX podría decirse que es una combinación de JavaScript y XML, y nos permite definir elementos de React usando una sintaxis basada en etiquetas directamente en nuestro código JavaScript, es decir, ya no necesitamos complicarnos la vida con la sintaxis compleja de createElement.
JSX
JSX también funciona con componentes, silo que de una forma mucho mas simple, nuestro componente tendrá un nombre definido que es el que usaremos en la etiqueta, hasta cierto punto es similar a crear un web component
Por ejemplo, el código moderno de un componente simple sería algo como esto:
const Users = (props) => {
const {names} = props;
return (
<ul>
{names.map((item, i) => <li key={i}>{item}</li>)}
</ul>
)
}
export default Users;
Y para usarlo lo definiríamos en el componente padre así:
<div className="App">
<Users names={users} />
</div>
Anidando componentes
Siguiendo con el ejemplo anterior, si quisiera algo mas granular y definir cada li como un componente independiente al cual le pueda definir mas propiedades, podemos hacerlo de la siguiente manera:
const User = (props) => {
const {name} = props;
return (
<li>
{name}
</li>
)
}
export default User;
En el componente padre, que ahora sería Users, tendriamos que importar el subcomponente e integrarlo
import User from './User';
const Users = (props) => {
const {names} = props;
return (
<ul>
{names.map((item, i) => <User key={i} name={item} />)}
</ul>
)
}
export default Users;
<div className="App">
<Users names={users} />
</div>
En este caso vemos como podemos ir anidando componentes hasta el nivel que necesitemos, en los ejemplos anteriores he usado algo como esto {name}, esto se conoce como JavaScript expressions, y es la forma en como podemos mostrar datos dinámicos en los componentes.
Otro punto importante, es que al mapear arrays, necesitamos usar un KEY, este identificador es usado por React para su referencia interna, lo pueden ver en los ejemplos al usar map, le paso al elemento una etiqueta key={i}.
Cual es el inconveniente de usar JSX? que el navegador no lo entiende, por eso toca usar compiladores como https://babeljs.io/ que convertirán el código de React a JavaScript puro. (Mas adelante voy a explicar esto a fondo).
React Fragments
Todo componente de React necesita estar dentro de un solo contenedor, usualmente usamos un div para envolver todo la estructura, pero si no deseamos que se renderice un elemento y queremos que solo se muestre el contenido, React nos ofrece una opción llamada fragmentos.
Para definir un fragmento lo podemos hacer de dos formas:
<React.Fragment></React.Fragment>
o de la forma simplificada
<></>
Ese elemento no será visible en el DOM.
Top comments (1)
Excelente post