Que es React?
Una biblioteca de JavaScript
para construir interfaces de
usuario
Surgimientos
Facebook
Jordan Walke
2013
Timeline
Principales características
Declarativo
Se basa en componenetes
Front-End
Open Source
Quienes lo utilizan?
Ventajas
Flujo de datos
unidireccional
Componentes de orden superior propagan
datos a los componentes de orden inferior.
Los de orden inferior trabajarán con esos
datos y cuando cambia su estado podrán
propagar eventos hacia los componentes de
orden superior para actualizar sus estados
Performance - DOM virtual
Gracias a la utilización de un DOM virtual
(ReactDOM) el cual se encuentra alojado en
memoria, optimiza la renderización de los
elementos/componentes de la página
Isomorfismo
Permite ejecutar código tanto del lado
cliente como del lado servidor.
También llamado "Javascript Universal".
Casos de prueba fáciles de escribir
Al estar compuesto por componentes, permite
testearlos demanera mas simple, su
estructura, sus estados, etc.
Recomendable: UnitTest (Jest)
Desventajas
Falta de documentación
oficial
El desarrollo súper rápido de ReactJS no deja
lugar para la documentación adecuada, que
ahora es un poco caótica, ya que muchos
desarrolladores contribuyen de forma
individual sin ningún enfoque sistemático
No ionizado
Los desarrolladores a veces tienen demasiadas
opciones
Curva de aprendizaje
Cuando se inicia, suele ser bastante
pronunciada
JSX
Sintaxis similar a XML/HTML que usa
React para hacer el render de los
componentes. Puedes usar etiquetas
HTML directamente para definir la
estructura de tu interfaz de usuario.
Babel, lo traduce en Javascript
interpretable por el navegador.
VirtualDOM
El Virtual DOM es una representación
en memoria del DOM del navegador
que actúa de intermediario entre el
estado de la aplicación y el DOM de la
interfaz gráfica que está viendo el
usuario. Este DOM virtual actualiza
solo las partes que han cambiado
Componentes
Basada en
Componentes
Toda nuestra aplicación esta
compuesta por clases o
funciones reutilizables con
funciones especificas
En React, las interfaces de usuario se componen de pequeños bloques
llamados "componentes". Los componentes son como piezas de LEGO
que se pueden ensamblar para construir una aplicación completa
Componentes Funcionales Componentes de clase
Tienen propiedades y Tienen propiedades /
estados estados, constructores,
métodos, Render().
Propiedades
Vienen provistas por el
padre a través de los
parámetros de la función y
pueden ser utilizadas por el
hijo pero no mutadas
dentro del ciclo de vida del
componente
Estados
Componentes Statefull
Componentes Stateless
First steps
vite
ViteJs
Es una de las herramientas
mas usadas hoy en día
(luego que se deprecara
CRA), para crear
aplicaciones de ReactJs
(entre otros) desde 0 con
las configuraciones
mínimas de un proyecto
<Documentación/>
nuevo.
Nuevo proyecto
1 npm create vite@latest
2
3 // Follow options and configurations
Correr el nuevo proyecto
1 cd <proyect-name>
2
3 npm install
4
5 npm run dev
Creando mi primer componente
1 // Borro los css y lineas innecesarias
2
3 function App() {
4 return (
5 <>
6 <h1>Hola clase de Programación III</h1>
7 </>
8 )
9 }
10
11 export default App
Próximos pasos
Código
1 // components/Alumno.jsx
2 function Alumno({legajo, condicion, mail}){
3 return (
4 <li>Legajo: {legajo}. Condición: {condicion}. {condicion === "Inscripto" && `Mail: ${mail}`}</li>
5 )
6 }
7 export default Alumno
8
9 // App.jsx
10 import { useState } from 'react'
11 import './App.css'
12 import listadoAlumnos from './data/alumnos.json'
13 import Alumno from './components/Alumno'
14
15 function App() {
16 const [isFiltered, setIsFiltered] = useState(false)
17 const [alumnos, setAlumnos] = useState(listadoAlumnos)
18
19 const onFilterClick = () =>{
20 setIsFiltered(isFiltered => !isFiltered)
21 if(isFiltered){
22 setAlumnos(listadoAlumnos.filter(a => a.legajo > 150000))
23 }else{
24 setAlumnos(listadoAlumnos)
25 }
26 }
27
28 return (
29 <>
30 <h1>Hola clase de Programación III</h1>
31 <h2>A continuación mostraremos el listado de alumnos de la clase</h2>
32 <div>
33 <button onClick={() => onFilterClick()}>{isFiltered ? "Quitar filtro" : 'Filtrar'} legajo mayor 150.000</button>
34 </div>
35 <ul>
36 {alumnos.map(a => <Alumno {...a}/>)}
37 </ul>
38 <p>Cantidad total de alumnos: {alumnos.length}</p>
39 </>
40 )
41 }
42
43 export default App
Objetivo Final
Scaffolding
Navegación
react-router-dom
Es necesario instalar 1
2
import
import
{Routes, Route, BrowserRouter} from "react-router-dom"
Home from "./modules/Home"
alguna librería para el
3 import About from "./modules/About"
4 import Contact from "./modules/Contact"
5 import Layout from "./components/Layout";
manejo de rutas/ruteo 6
7 function App() {
dentro de la app 8
9
return (
<div className="App">
10 <BrowserRouter>
11 <Routes>
1 npm i react-router-dom 12 <Route element={<Layout />} >
13 <Route path="/" element={<Home />} />
14 <Route path="about" element={<About />} />
Y consta de dos partes:
15 <Route path="contact" element={<Contact />} />
16 </Route>
17 </Routes>
una parte en donde se 18
19
</BrowserRouter>
</div>
mapean las rutas para 20
21 }
)
que la app reconozca las 22
23 export default App
urls y que componente
renderiza con cada item <Documentación/>
Layout
1 import { NavLink, Outlet } from "react-router-dom";
2 export default function Layout() {
Y otro componente que 3 const menuItems = [
4 { href: '/', title: 'Introduction' },
nos permita navegar en 5
6
{ href: 'about', title: 'About' },
{ href: 'contact', title: 'Contact' }
estas rutas. De lo 7
8
];
contrario, vamos a tener
9 return (
10 <div>
11 <header> Menu </header>
que en la barra de 12
13
<div >
<nav>
navegación tipar siempre 14
15
<ul>
{menuItems.map(({ href, title }) => (
las urls 16
17
<li key={title}>
<NavLink to={href} >
18 <p>{title}</p>
19 </NavLink>
20 </li>
21 ))}
22 </ul>
23 </nav>
24 <main>
25 <Outlet />
26 </main>
27 </div>
28 </div>
29 );
30 }
<Documentación/>
Prettier + Linters
Prettier
"Mas bonito" en ingles,
justamente sirve para eso.
Es un formateador de código,
configurable por reglas para
que todo el código luzca igual.
<SitioOficial/>
Es muy util para dar legibilidad
al código y para trabajo en
equipo
Ejemplo
1 // Sin Prettier
2 import { useState } from 'react';import reactLogo from './assets/react.svg';import viteLogo from '/vite.svg';
3 import './App.css';function App() {const [count, setCount]= useState(0)
4 return (<><div><a href="https://vitejs.dev" target="_blank"><img src={viteLogo} className="logo" alt="Vite logo" /></a>
5 <a href="https://react.dev" target="_blank"><img src={reactLogo} className="logo react" alt="React logo" /></a></div>
6 <h1>Vite + React</h1>
7 <div className="card">
8 <button onClick={() => setCount((count) => count + 1)}>count is {count}</button></div>
9 <p className="read-the-docs">Click on the Vite and React logos to learn more</p></>)}export default App
1 // Con PRETTIER
2 import { useState } from 'react'
3 import reactLogo from './assets/react.svg'
4 import viteLogo from '/vite.svg'
5 import './App.css'
6
7 function App() {
8 const [count, setCount] = useState(0)
9
10 return (
11 <>
12 <div>
13 <a href="https://vitejs.dev" target="_blank">
14 <img src={viteLogo} className="logo" alt="Vite logo" />
15 </a>
16 <a href="https://react.dev" target="_blank">
17 <img src={reactLogo} className="logo react" alt="React logo" />
18 </a>
19 </div>
20 <h1>Vite + React</h1>
21 <div className="card">
22 <button onClick={() => setCount((count) => count + 1)}>
23 count is {count}
24 </button>
25 </div>
26 <p className="read-the-docs">
27 Click on the Vite and React logos to learn more
28 </p>
29 </>
30 )
31 }
32
33 export default App
Instalación
1 // Install
2
3 npm install --save-dev --save-exact prettier
4
5 // Create .prettierrc.json with:
6
7 {
8 "trailingComma": "es5", <Documentación/>
9 "tabWidth": 4,
10 "semi": false,
11 "singleQuote": true
12
13
}
(*) Se puede configurar
14
15
// Ignore files by ".prettierignore" or lines:
para los distintos
16
17
{/* prettier-ignore */}
IDEs/Editores plugins
18
19
// You can integrate with linters
// EX. eslint-config-prettier plugin que funcionen en
paralelo con las
20
21 // You can configure a pre-commit hook
configuraciones dadas
22 // On .pre-commit-config.yaml file paste:
23
24 - repo: https://github.com/pre-commit/mirrors-prettier
25 rev: "" # Use the sha or tag you want to point at
26 hooks:
27 - id: prettier
EsLint
Es un analizador de código
(linter) que permite detectar
errores estáticos.
Puede encontrar variables no
usadas, propiedades que no
fueron declaradas, funciones
no exportadas/importadas,
etc.
Se puede configurar con
muchas reglas haciendo mas
estricto sus controles
Instalacion
1 Install
2
3 npm install --save-dev eslint
4
5 configure by .eslintrc file: <Documentación/>
6
7 module.exports = {
8 "env": {
9 "browser": true,
10 "es2021": true
11
12
},
"extends": "eslint:recommended",
(*) Se puede configurar
13
14
"parserOptions": {
"ecmaVersion": "latest",
para los distintos
15
16 },
"sourceType": "module"
IDEs/Editores plugins que
17
18
"files": ["bin/*.js", "lib/*.js"],
"excludedFiles": "*.test.js",
funcionen en paralelo con
19
20
"rules": {
"quotes": ["error", "single"]
las configuraciones dadas
21 }
22 }
23
Hooks
useState
Sirve para manejar el estado de
un componente.
Se declara un estado y una
función asociada a ese estado
que permite modificarlo (no se
permite la modificación
directa).
También es recomendable
cuando se declara, asociarle el
tipo de objeto a utilizar en ese
estado
<OtrosEjemplos />
useEffect
Sirve para manejar efectos
laterales; como ser llamadas a
sitios externos, timers, etc.
Como primer parámetro recibe
una función y luego las
dependencias (opcional).
Las dependencias pueden ser:
vacio: corre en cada
renderizado
[]: corre solamente en el
primer renderizado
[item1, item2...]: corre en el
primer renderizado y cada vez <OtrosEjemplos />
que una dependencia cambie
useContext
Sirve para manejar estados
globales.
Recibe como parámetro el
contexto a manipular.
También ese contexto es creado
con la función createContext()
que recibe un valor por defecto en
caso de ser necesario.
Todos los componentes que
quieran acceder a ese contexto,
deben estar dentro de un
<Context.Provider /> <OtrosEjemplos />
useCallback
Sirve para almacenar/cachear una
función entre renderizados
subsecuentes.
Se utiliza para mejorar la
performance y evitar el re-
renderizado de componentes.
En el renderizado inicial,
devuelve la función.
En los siguientes renderizados,
devuelve la función ya
almacenada, o si las
dependencias cambiaron,
devuelve la función que hayas
enviado durante el renderizado
actual. <OtrosEjemplos />
useMemo
Sirve para almacenar/cachear un
valor entre renderizados
subsecuentes.
Se utiliza para mejorar la
performance y evitar el re-
renderizado de componentes.
En el renderizado inicial,
devuelve la valor que calcula la
función pasada.
En los siguientes renderizados,
devuelve el valor ya
almacenado, o si las
dependencias cambiaron,
calcula el valor nuevamente.
<OtrosEjemplos />
useId
Sirve para generar IDs únicos que
se pueden pasar a los atributos de
accesibilidad.
Es un hook, se utiliza solo a nivel
superior de un componente.
NO deben usars para generar keys
de listas
<OtrosEjemplos />
useRef
Sirve para guardar la referencia a
un elemento o guardar un valor
independientemente de los re-
renderizados del componente.
Al mutar el valor del current, no se
re-renderiza el componente.
La mejor manera de acceder al
valor/modificarlo es dentro de un
useEffect o dentro de
controladores de función (ej:
handleSubmit)
<OtrosEjemplos />
useReducer
Sirve para guardar la referencia a
un elemento o guardar un valor
independientemente de los re-
renderizados del componente.
Al mutar el valor del current, no se
re-renderiza el componente.
La mejor manera de acceder al
valor/modificarlo es dentro de un
useEffect o dentro de
controladores de función (ej:
handleSubmit)
<OtrosEjemplos />
Custom Hooks
Basicamente es una función que
se reutiliza en varios lados.
La diferencia con una función
normal de javascript, es que
también maneja el useState y el
useEffect dentro y siempre se
llaman "use<CustomName>"
<OtrosEjemplos />
Recommended Libraries
Http client
1 // servicies/api.js
Cliente HTTP basado en 2
3
import axios from 'axios'
import localStorage from './localStorage'
promesas para el navegador y 4
5 const api = axios.create({
node.js 6
7
baseURL: 1000 * 15, // 15 sec
timeout: "http://localhost:4000/",
8 headers: {
9 Accept: 'application/json',
10 'Content-Type': 'application/json',
Es muy util para hacer 11
12 })
},
llamadas a los distintos 13
14 api.interceptors.request.use(
endpoints, es de fácil 15
16
config => {
const data = localStorage.get() // Before request is sent
17 if (data) {
configuración y utilización 18 // eslint-disable-next-line no-param-reassign
19 config.headers.common.Authorization = `${data.token}`
20 }
21 return config
22 },
Cuenta con interceptors que 23
24
error =>
Promise.reject(error) // Do something with request error
son funciones que se ejecutan 25
26
)
antes y despues de procesar 27
28
api.interceptors.response.use(
response =>
los requests y los responses 29
30
response.data, // Do something with response data
error =>
31 // Do something with response error
32 Promise.reject(errorMessage(error))
33 )
<Documentación /> 34
35 export default api
Configs
Sirven para configuraciones
particulares de cada ambiente 1 .env.development
(desarrollo, producción, 2
3
VITE_APP_TITLE="My APP"
VITE_API_URL="http://localhost:3000/"
testing, etc). 4
5
VITE_DEFAULT_THEME=dark
6 .env.production
Están compuestas por url, 7 VITE_APP_TITLE="BayloApp"
8 VITE_API_URL="https://baylo-api/"
secrets, keys, etc. 9 VITE_DEFAULT_THEME=ligth
Se alojan en archivos .env,
.env.local, etc
VITE: Se antepone el prefijo
"VITE_" para que el entorno
las considere
<Documentación />
Component UI
AntD / MaterialUI
Sirve para simplificar y acelerar el
proceso de desarrollo de interfaces
1 npm install antd --save
de usuario. Proporcionan un 2
3 // App.jsx
conjunto de componentes 4 import React from 'react';
5 import { Button } from 'antd';
predefinidos y estilizados que 6
7 const App = () => (
puedes utilizar en tus aplicaciones 8
9
<div className="App">
<Button type="primary">
10 Button
1. Reutilización de 11 </Button>
12 </div>
Componentes. 13 );
14
2. Diseño Consistente. 15 export default App;
3. Facilidad de Personalización.
4. Mejora de la Productividad. <ComponentesAntD />
<AntD />
<MaterialUI />
FormiK
1 npm install formik
2
3 import React from 'react';
4 import ReactDOM from 'react-dom';
5 import { Formik, Field, Form } from 'formik';
Librería utilizada para facilitar la 6
7 const Basic = () => (
gestión y validación de 8
9
<div>
<h1>Sign Up</h1>
formularios. Simplifica 10
11
<Formik
initialValues={{ firstName: '', lastName: '', email: '' }}
significativamente la 12
13
onSubmit={async (values) => {
await new Promise((r) => setTimeout(r, 500));
implementación de formularios y 14
15 }}>
alert(JSON.stringify(values, null, 2));
ofrece una forma más declarativa 16
17
<Form>
<label htmlFor="firstName">First Name</label>
y organizada de manejar la entrada 18
19
<Field id="firstName" name="firstName"
placeholder="Jane" />
de datos y las validaciones. 20
21
<label htmlFor="lastName">Last Name</label>
<Field id="lastName" name="lastName"
Características: 22 placeholder="Doe" />
23 <label htmlFor="email">Email</label>
24 <Field
1. Gestión de Estado del 25 id="email"
26 name="email"
Formulario 27 placeholder="
[email protected]"
28 type="email"
2. Gestión de Valores Iniciales 29 />
30 <button type="submit">Submit</button>
3. Validación del Formulario 31
32
</Form>
</Formik>
33 </div>
4. Mensajes de Error 34 );
35
5. Manejo de Envío 36 ReactDOM.render(<Basic />, document.getElementById('root'));
6. Extensible y Personalizable
<Documentación />
Authentication
localStorage
lscache
1 npm install lscache
2
3 // services/localStorage.js
4 import lscache from 'lscache'
5
6 // enable warnings
Es una librería de JavaScript 7
8
if (process.env.NODE_ENV !== 'production') {
lscache.enableWarnings(true)
que se utiliza para 9
10
}
almacenar datos en el 11
12
const tokenKey = '__EduSearch__' // More secure on a config
const duration = 86400000 // 24hs in milliseconds
13 const localStorage = {}
almacenamiento local 14
15 // Set token
(localStorage) del 16
17
localStorage.set = user => lscache.set(tokenKey, user, duration)
navegador. Aunque puede 18
19
// Get token
localStorage.get = () => lscache.get(tokenKey)
ser utilizado para 20
21 // Delete token
almacenar tokens de 22
23
localStorage.delete = () => lscache.flush()
autenticación, es
24 // Get user
25 localStorage.getUser = () => lscache.get(tokenKey)?.user
26
importante tener en cuenta 27 // Update user
28 localStorage.updateUser = updatedUser => {
la seguridad 29
30
const storageData = lscache.get(tokenKey)
storageData.user = updatedUser
31 localStorage.set(storageData)
32 }
33
34 export default localStorage
<Documentación />
React Native
Permite crear aplicaciones
nativas para cada plataforma en
particular
Diferencias con ReactJs (Medium)
Documentación oficial: https://facebook.github.io/react-native/
Expo: https://expo.dev/
Documentación
Documentación (español)
Babel
Codepen
CodeSandBox
VirtualDOM Medium
AntDesign
MaterialUI
Formik - Build Forms in React