Learning-path para React basics
Ésta guía fue creada con CRA en mente. Desde ésta actualización, la documentación oficial ha cambiado de CRA a usar frameworks para la creación de aplicaciones React
- HTML
- CSS
- JavaScript
- Node
- npm
- Terminal
Ver la primer hora del curso de React de Bob Ziroll
La forma más sencilla de crear una nueva aplicación en React es utilizando el toolchain para ambiente de desarrollo create-react-app
.
Verificar Node >= 14.0.0 y npm >= 5.6
En una nueva carpeta, utilizar la terminal para ejecutar las siguientes lineas de comando
npx create-react-app my-app
cd my-app
npm start
Después de ejecutar, deberíamos ver algo así
src
contiene todos los archivos esenciales para nuestro proyecto- En la carpeta public se encuentra el archivo html incial
index.html
. Este puede ser modificado como cualquier archivo.html
.
- Directorio
src
App.js
es el archivo principal de nuestra aplicación. Todos los componentes tendrán conexión a éste archivo.index.js
es un archivo de inicio de la aplicación. Aquí se hace referencia al elemento html conid root
para su renderización en el DOM.App.css e index.css
contienen estilos de la aplicación.index.css
contiene estilos globales.App.css
contiene estilos más especificos para componentes.
Sintáxis JavaScript XML que permite escribir elementos HTML en JavaScript, para colocarlos dentro del DOM sin la necesidad de utilizar document.createElement()
o appendChild()
.
Creación de elementos HTML con
document.createElement()
var tag = document.createElement("p");
Creación de elementos HTML con
JSX
const App = () => {
return (
<div className="App">
<h1>Hello World</h1>
</div>
)
}
export default App;
export default Component
se refiere al componente que se va a exportar de nuestro archivo Componente.js
. De ésta forma se envían componentes a otros archivos .js
para su funcionamiento.
- Todos los elementos dentro de un componente deben estar encapsulados en un solo elemento html. Puede ser
<div>
o el elemento React.Fragment dejsx
:
<>
<h2>Los demás elementos van aquí</h2>
<div>
<p>Deben estar encapsulados</p>
</div>
</>
-
Real DOM
Lo conocemos como Document Object Model y representa la UI de la aplicación.
Cuando hay algún cambio, el DOM se actualiza en su totalidad.
-
Virtual DOM
Es una representación virtual del DOM real. Similar a un DOM temporal.
Cuando se agregan/eliminan/modifican elementos, el árbol del Virtual DOM se actualiza.
Luego, se compara Virtual DOM con el Real DOM para encontrar los nodos en el árbol que han cambiado.
Cuando se encuentran las diferencias, Virtual DOM encuentra la mejor forma de actualizar nodos especificos del Real DOM sin la necesidad de actualizarlo en su totalidad.
Se pueden comparar con bloques de construcción de Lego. Cada componente es un bloque de piezas que representa una sección del modelo completo.
Estos componentes tienen como tarea hacer la construcción de la UI más fácil, dividiendo el problema de la app en piezas individuales que se pueden reutilizar.
La división de los componentes generalmente ayudan a separar su estructura global en secciones que puedan funcionar de forma individual. Los componentes más comúnes son:
- Inputs
- Botones
- Badge
- Lista
- Tabla
- NavBar
- Alert
- Card
- Tabs
- Select
Son simplemente funciones de javascript. Pueden o no recibir datos por medio de parámetros. Este tipo de componentes no toman en cuenta la existencia de otros componentes dentro de la aplicación.
import React from 'react';
const Navbar = () => {
return (
<nav>
// etc
</nav>
)
}
export default Navbar;
Este tipo de componentes si están conectados con otros componentes y pueden comunicarse enviándose datos uno a otro.
El uso de componentes funcionales es común cuando se sabe de antemano que ese componente no tendrá interactividad con otro.
import React, { Component } from 'react';
class Navbar extends React.Component {
render() {
return (
<nav>
// etc
</nav>
)
}
}
export default Navbar;
Sean componentes funcionales o de clase, se pueden importar e implementar en la app de una forma muy sencilla. Para renderizarlos simplemente tenemos que importar el componente.js
a el archivo de la página donde se va a renderizar, para SPAs comúnmente es App.js
. Para componentes que se implementarán dentro de otro componente, la sintáxis es la misma
import Navbar from './Components/Navbar/Navbar.js';
const App = () => {
return (
<>
<Navbar />
<Carousel />
<Main />
<Contact />
</>
);
}
export default App;
Para independizar los componentes en sus propios archivos es comúnmente utilizado el aplicar estilos css
por medio de clases className="menu navigation-menu"
y en un archivo externo de .css
colocar los estilos por #id
o .clase
.
Similar a ingresar estilos con el atributo style
de html, se pueden agregar estilos para un elemento utilizando JSX.
const divStyle = {
color: 'blue',
backgroundImage: 'url(' + imgUrl + ')',
};
const MenuComponent = () => {
return (
<nav className="navbar" style={divStyle}>
<a className="navbar-a">Home</a>
</nav>
)
}
O bien,
// Result style: '10px'
<div style={{ height: 10 }}>
Hello World!
</div>
// Result style: '10%'
<div style={{ height: '10%' }}>
Hello World!
</div>
Similar a importar un archivo styles.css
dentro de nuestro index.html
, se pueden implementar archivos .css
dentro de un componente. Aplicando estilos por class
o id
.
Navbar.js
import './Navbar.css';
const Navbar = () => {
return(
<nav className="navbar">
<a className="navbar-a">Home</a>
</nav>
)
}
export default Navbar;
Navbar.css
.navbar {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
.navbar-a {
font-size: 2rem;
}
La estructura del proyecto utilizando archivos .css
externos se ve de la siguiente forma:
project
│ README.md
│ package.json
│ ...
│
└───src
│ │ App.js
│ │ App.js
│ │ ...
│ │
│ └───Components
│ │
│ └───Navbar
│ │ Navbar.css
│ │ Navbar.js
│ │
│ └── ...
Props
se refiere a propiedades. Argumentos de objetos con datos que le envíamos al componente para aplicarlo dentro de su lógica.
Se utiliza props para aumentar significativamente la reusabilidad de los componentes en una aplicación, transformando la información que se comparte en información dinámica, y/o utilizando estos datos para modificar el componente.
Podemos utilizar props dentro de un componente de la misma forma en la que aceptamos argumentos en una función.
Header.js
import React from 'react';
const Header = (props) => {
const name = props.name;
const lastName = props.lastName;
return (
<div>
<h1>Hola, {name}, {lastName}</h1>
</div>
)
}
export default Header;
Para enviar datos hacia ese componente, lo hacemos de la misma forma como utilizamos atributos dentro de una etiqueta html
.
App.js
import Navbar from './Components/Navbar/Navbar.js';
//etc...
const App = () => {
return (
<>
<Navbar />
<Header name="Griselo" lastName="Philip">
<Carousel />
<Main />
<Contact />
</>
);
}
export default App;
A diferencia del método anterior, podemos declarar cada prop individual desde que los tomamos como parámetros en nuestro componente.
App.js
se mantiene igual
Header.js
import React from 'react';
const Header = ({name, lastName}) => {
return (
<div>
<h1>Hola, {name}, {lastName}</h1>
</div>
)
}
export default Header;
Para evitar confusión y mejorar UX, es común utilizar default props como valores predeterminados que serán utilizados en caso de que los parámetros fallen, o no se haga el fetch de manera correcta.
Estos default props se crean directamente en el componente
Header.js
import React from 'react';
const Header = (name, lastName) => {
return (
<div>
<h1>Hola, {name}, {lastName}</h1>
</div>
)
}
// Aqui declaramos default Props
Header.defaultProps = {
name: "Nombre",
lastName: "Apellido"
}
export default Header;
Javascript tiene el operador spread, que es de gran utilidad al momento de enviar muchos datos a un componente, sin la necesidad de especificar cada uno como atributo dentro de la etiqueta del componente.
App.js
import Navbar from './Components/Navbar/Navbar.js';
//etc...
const App = () => {
// Definir los datos
const user = {
name: "Griselo",
lastName: "Philip"
};
return (
<>
<Navbar />
// Se envian los datos
<Header {...user}>
<Carousel />
<Main />
<Contact />
</>
);
}
export default App;
Renderizado condicional es la forma en que React permite mostrar ciertos datos en la interfaz cuando se cumplan ciertas condiciones lógicas.
Se pueden utilizar de forma condicionales
if - else
condition &&
o, más comúnmente, con el operador ternario
condition ? exprIfTrue : exprIfFalse
Condition: expresión lógica a evaluar
exprIfTrue: Lógica a ejecutar si es verdadero
exprIfFalse: Lógica a ejecutar si es falso
If - else
// Renderizado de icono de perfil, si esta iniciada la sesión
// Renderizado de Boton si no
const Navbar = (props) => {
return (
<nav>
<div clasName="logo">
// code here
</div>
{
if(props.isLogged) {
return(<UserIcon />)
} else {
return (<LoginButton />)
}
}
</nav>
)
}
export default Navbar;
Ternary
// Misma lógica al ejemplo anterior
const Navbar = (props) => {
return (
<nav>
<div clasName="logo">
// code here
</div>
{
props.isLogged ? (<UserIcon />) : (<LoginButton />)
}
</nav>
)
}
export default Navbar;
&&
// Misma lógica al ejemplo anterior
const Navbar = (props) => {
return (
<nav>
<div clasName="logo">
// code here
</div>
{
props.isLogged && <UserIcon />
}
</nav>
)
}
export default Navbar;
Material UI es una librería open-source para React que hace uso e implementa el diseño Diseño material de Google.
Se instala en nuestro proyecto por medio de npm o yarn.
npm
npm install @mui/material @emotion/react @emotion/styled
Yarn
yarn add @mui/material @emotion/react @emotion/styled
Emotion es una librería que permite utilizar y diseñar CSS dentro de javascript. Se puede sustituir por la libreria de styled-components, de la siguiente forma:
npm install @mui/material @mui/styled-engine-sc styled-components
yarn add @mui/material @mui/styled-engine-sc styled-components
nota
-
@mui/material no contiene iconos. Para agregar a nuestro proyecto lo podemos hacer mediante npm
-
Para instalar fuentes, se puede hacer por medio de CDN, o vía NPM siguiendo las instrucciones de google fonts.
npm install @mui/icons-material
yarn add @mui/icons-material
- Layout
- Display
React Router es una librería para agregar client y server-side routing a páginas hechas con React y/o ReactNative.
npm
npm install react-router-dom@6
nota
- Se utiliza la denominación 6 por la versión activa a la fecha de la creación de éste documento.
Importar BrowserRouter
dentro de nuestro index.js
en nuestra app y agregar el componente a nuestra app.
index.js
import React from "react";
import ReactDOM from "react-dom/client";
import { BrowserRouter } from "react-router-dom";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
const root = ReactDOM.createRoot(
document.getElementById("root")
);
root.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>
);
Esto nos da la libertad de utilizar React Router en cualquier parte de nuestra aplicación.
App.js
import './App.css';
import React from 'react';
import { Routes, Route, Link } from 'react-router-dom';
import Navbar from './Components/Navbar/Navbar';
import Astronauts from './Components/Astronauts/Astronauts';
import APOD from './Components/APOD/APOD';
function App() {
// class = "";
// className = "";
// Todos los elementos deben estar en una etiqueta padre
const data = {
name: "Griselo",
lastName: "Philip"
};
return (
<div className="App">
{/* <ResponsiveAppBar /> */}
<Navbar {...data} />
<Routes>
<Route path='/astronauts' element={<Astronauts />} />
<Route path='/apod' element={<APOD />} />
</Routes>
</div>
);
}
export default App;
Para aplicar estos links a cualquier parte de nuestra app es suficientE:
Nabvar.js
import {Link} from 'react-router-dom';
import './Navbar.css';
const Navbar = ({ name, lastName }) => {
return (
<nav className="navbar">
<div className="nav-container">
<div className='nav-left'>
<a href='/'>
<img alt='space-logo' className='nav-img' src="https://cdn.dribbble.com/users/1769954/screenshots/4216600/media/f1ed192ec1c5300d413fac7fb076f7d0.png"></img>
</a>
<h1 className='nav-title'>Space-app</h1>
</div>
<div className="nav-links">
<Link to="/astronauts">People in space</Link>
<Link to="/apod">Astronomy pic of the day</Link>
</div>
</div>
</nav>
)
}
Navbar.defaultProps = {
name: "Nombre",
lastName: "Apellido"
}
export default Navbar;