10 | );
11 | };
12 |
13 | // Usamos memo para optimizar el componente
14 | export default memo(MiComponente);
15 |
16 | // React memo se utiliza para evitar que un componente funcional se vuelva a renderizar a menos que sus propiedades (props) hayan cambiado.
17 | // Funciona creando una version memorizada (cache) del componente y comparando las propiedades antiguas con las nuevas antes de decidir si se debe realizar un nuevo renderizado.
18 | // Esto puede ser especialmente util cuando tenes componentes funcionales que no dependen de cambios en las propiedades.
--------------------------------------------------------------------------------
/Clase-12/components/memoEjemplo/index.jsx:
--------------------------------------------------------------------------------
1 | import React, {memo} from 'react';
2 | import styles from './styles.module.css'
3 | import MiComp from '../miComp';
4 |
5 | const Contador = ({ title, cont, setCont }) => {
6 |
7 | // console.log(`Renderizando ${title}`);
8 |
9 | return (
10 |
53 | );
54 | }
55 |
56 |
57 |
58 | export default App;
59 |
--------------------------------------------------------------------------------
/Clase-13/firebase/client.js:
--------------------------------------------------------------------------------
1 | import {initializeApp} from "firebase/app"
2 | import {getFirestore} from 'firebase/firestore'
3 |
4 | const firebaseConfig = {
5 | // Aca va el objeto que nos da Firebase:
6 | apiKey: "",
7 | authDomain: "",
8 | projectId: "",
9 | storageBucket: "",
10 | messagingSenderId: "",
11 | appId: ""
12 | };
13 |
14 | const app = initializeApp(firebaseConfig);
15 | export const db = getFirestore(app);
--------------------------------------------------------------------------------
/Clase-14/App.jsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useState } from "react";
2 | import './App.css';
3 |
4 | import { db } from "./firebase/client";
5 |
6 | // collection es una funcion de firestore
7 | import {getDocs, collection, query, where, limit, getDoc, doc, addDoc, updateDoc, writeBatch } from 'firebase/firestore'
8 |
9 |
10 | function App() {
11 | const [products, setProducts] = useState([])
12 | // Traer toda la data de una coleccion de firebase:
13 | const productsRef = collection(db, "products")
14 |
15 | const getProducts = async () => {
16 | const data = await getDocs(productsRef)
17 | const dataFiltrada = data.docs.map((doc) => ( {...doc.data(), id: doc.id} ))
18 | console.log(dataFiltrada)
19 | setProducts(dataFiltrada)
20 | }
21 |
22 | // Para obtener un documento especifico:
23 | const productRef = doc(db, "products", "RDIjhYFRE455GU9sKujt")
24 | const getProduct = () => {
25 | getDoc(productRef).then((snapshot => {
26 | if(snapshot.exists()){
27 | // console.log(snapshot)
28 | console.log( { id: snapshot.id, ...snapshot.data() } )
29 | }
30 | }))
31 | }
32 |
33 | // Crear un DOC y una collection (En el caso de que no exista)
34 | const createOrder = () => {
35 | const order = {
36 |
37 | buyer: {name: "Abel", phone: "1155889966", email: "abel@abel.com"},
38 | items: products[1],
39 | // items: cart
40 | total: products[1].price
41 | // total: totalCart
42 | }
43 |
44 | const orderCollection = collection(db, 'orders')
45 |
46 | addDoc(orderCollection, order).then(({id}) => console.log(id))
47 | }
48 |
49 | // Hacer un update de un DOC
50 | const updateOrder = (id) => {
51 | const orderToUpdate = doc(db, "orders", id)
52 | updateDoc(orderToUpdate, { total: 99}) // Segundo parametro: Los campos que quiero updatear
53 | }
54 |
55 | // Distintas Operaciones en una sola func
56 | const updateMultipleDocs = async () => {
57 | const batch = writeBatch(db);
58 |
59 | // Setea nuevos campos a un doc. OJO
60 | const orderRef = doc(db, "orders", "IfdlpJ6jp6897V3wZJmF");
61 | batch.set(orderRef, {stockOferta: 20});
62 |
63 | // Actualiza uno o varios campos de un doc.
64 | const productRef = doc(db, "products", "uYfqWZ1BtyCGjNs3B54l");
65 | batch.update(productRef, {"stock": 99});
66 |
67 | // Borra un doc
68 | const deleteProdRef = doc(db, "products", "dSPGco0xb3BOyOCSLhAz");
69 | batch.delete(deleteProdRef);
70 |
71 | // Commit del batch
72 | await batch.commit();
73 | }
74 |
75 | useEffect(() => {
76 | // getProduct()
77 | getProducts()
78 | }, []);
79 |
80 |
81 |
82 | return (
83 |
84 |
85 |
86 | {products?.map(pr => {
87 | return(
88 |
89 |
{pr.title}
90 |
{pr.description}
91 |
{pr.price}
92 |
93 | )
94 | })}
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 | );
104 | }
105 |
106 |
107 |
108 | export default App;
109 |
--------------------------------------------------------------------------------
/Clase-2/clase2.txt:
--------------------------------------------------------------------------------
1 | DOM y Virtual DOM
2 |
3 | Inicialización: Cuando una aplicación React se inicia, se crea un Virtual DOM que replica el DOM real del navegador.
4 |
5 | Actualización: Cuando se produce un cambio en el estado o en los datos de la aplicación, se genera un nuevo Virtual DOM para representar esa nueva versión del interfaz.
6 |
7 | Diferenciación: React compara este nuevo Virtual DOM con el anterior para identificar cuál es la diferencia entre los dos. Este proceso se llama "Reconciliación".
8 |
9 | Actualización del DOM real: Solo las partes que han cambiado en el Virtual DOM se actualizan en el DOM real, en lugar de volver a renderizar todo el DOM. Este enfoque optimiza el rendimiento y mejora la eficiencia en términos de recursos computacionales.
10 |
11 | Ventajas del Virtual DOM
12 | Optimización del rendimiento: Al no tener que manipular todo el DOM real para cada cambio, se mejora significativamente el rendimiento.
13 |
14 | Desarrollo más sencillo: Los desarrolladores no tienen que preocuparse tanto por cómo y cuándo se actualiza el DOM, ya que React maneja esto de forma eficiente.
15 |
16 | Mayor consistencia: Dado que React se encarga de administrar el Virtual DOM y el DOM real, las posibilidades de errores o comportamientos inconsistentes se reducen.
17 |
18 | Ejemplo sencillo
19 | Imaginense que tienen una lista de elementos y solo quieren actualizar uno de ellos. En una implementación tradicional del DOM, quizás tendrían que volver a renderizar toda la lista para reflejar este cambio. Sin embargo, con el Virtual DOM, solo se actualizaría el elemento específico que cambió, dejando el resto de la lista intacta. Esto es mucho más eficiente.
20 |
21 | En resumen, el Virtual DOM es una capa de abstracción que permite a React optimizar el rendimiento de la aplicación al minimizar las costosas operaciones de manipulación del DOM real.
--------------------------------------------------------------------------------
/Clase-3/clase3.js:
--------------------------------------------------------------------------------
1 | // const condition = true
2 |
3 | // if (1 == 2) {
4 | // return true
5 | // } else {
6 | // return false
7 | // }
8 |
9 | // 1 == 2 ? true : false
10 |
11 |
12 | // if ( 1 == 1 ) return true
13 | // 1 == 1 && true
14 |
15 |
16 | // Desestructuracion:
17 |
18 | // const coder = {
19 | // curso: "ReactJs",
20 | // profesor: "Luciano",
21 | // alumnos: 50,
22 | // }
23 |
24 | // const { curso, profesor, alumnos } = coder
25 |
26 | // console.log(curso)
27 | // console.log(profesor)
28 |
29 | // Propiedades dinamicas:
30 | // const año = 2025;
31 |
32 | // const objeto = {
33 | // nombre: "luciano",
34 | // [ "propDinamica" + año ]: "coders"
35 | // };
36 |
37 | // console.log(objeto);
38 |
39 | // // Salida:
40 | // // {
41 | // // nombre: 'luciano',
42 | // // propDinamica2023: 'coders'
43 | // // }
44 |
45 |
46 |
47 |
48 | // Comparacion de objetos:
49 | // const primerObjeto = {
50 | // nombre: 'Luciano'
51 | // }
52 |
53 | // const segundoObjeto = {
54 | // nombre: 'Luciano'
55 | // }
56 |
57 |
58 | // console.log(primerObjeto == segundoObjeto) // False
59 | // console.log(JSON.stringify(primerObjeto) === JSON.stringify(segundoObjeto)); // True
60 |
61 |
62 |
63 |
64 |
65 |
66 | // Spread operator:
67 | // const alumnosArray = ['Juan', 'Marce', 'Luis', 'Mica', 'Luz']
68 |
69 | // const alumnosNuevosArray = ['Manu', 'Azul', 'Chiara']
70 |
71 | // console.log( [...alumnosArray, ...alumnosNuevosArray ] )
72 |
73 | // const alumnosTotal = [...alumnosArray, ...alumnosNuevosArray]
74 | // console.log(alumnosTotal)
75 |
76 | // ...alumnosArray = 'Juan', 'Marce', 'Luis', 'Mica', 'Luz'
77 | // ...alumnosNuevosArray = 'Manu', 'Azul', 'Chiara'
78 |
79 |
80 | // const alumnosTotalSinSpread = [alumnosArray, alumnosNuevosArray]
81 | // console.log(alumnosTotalSinSpread)
82 |
83 |
84 | // const arrayEjemplo = [1, 2, 3, 4]
85 |
86 | // const nuevoValor = 10
87 |
88 | // const nuevoArray = [...arrayEjemplo, nuevoValor, 22, 'Hola']
89 |
90 | // console.log(nuevoArray)
91 | // const nuevo = [...arrayEjemplo]
92 |
93 |
94 |
95 |
96 |
97 |
98 | // EJERCICIO:
99 |
100 | // Crear una funcion que pasandole un numero y un array como parametro lo que haga es:
101 | // Si el valor se encuentra dentro del array lo elimine
102 | // Si el valor no esta dentro del array lo agregue
103 | // RETORNE ARRAY console.log(arrayDeResultado)
104 |
105 |
106 | // Solución:
107 |
108 | const filtrarNumeros = (numero, array) => {
109 | const estaDentroDelArray = array.find(n => n == numero)
110 |
111 | if(estaDentroDelArray){
112 | return array.filter(n => n != numero)
113 | } else {
114 | return [numero, ...array]
115 | }
116 | }
117 |
118 | // Cuando se cumple cualquiera de las dos condiciones el array debe devolverse ordenado de menor a mayor
119 |
120 | console.log(filtrarNumeros(1, [2, 3]))
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 | // let valores = [2, 6, 9, 0, '8']
136 |
137 | // 0 == '0' : true
138 | // 0 === '0' : false
139 |
140 | // 0 !== '0' : true
141 | // 0 != '0' : false
142 |
143 | // true ? console.log('es true') : console.log('es false')
144 | // const miValorNuevo = 10
145 | // miValorNuevo == 10 && console.log('es true')
146 |
147 | // Ayudas: podemos utilizar un .find() para ver si el valor se encuentra dentro del array
148 |
149 |
150 | // const filterNumber = (number, array) => {
151 | // const isIn = array.find((n) => n == number)
152 |
153 | // if(isIn){
154 | // return array.filter((n) => n != number)
155 | // } else {
156 | // return [...array, number]
157 | // }
158 | // }
159 |
160 | // console.log(filterNumber('1', [10, 20, 1, 3]))
161 | // console.log(filterNumber(1, [10, 20, 3]))
162 |
163 |
164 |
165 | // Desestructuracion de array u objetos
166 | // const objetoDesestructuracion = {
167 | // comision: '9999',
168 | // alumnos: 103,
169 | // clases: 15,
170 | // tema: 'ReactJs'
171 | // }
172 |
173 | // // Queremos acceder al numero de comision y de alumnos:
174 | // const nroDeComision = objetoDesestructuracion.comision
175 | // const nroDeAlumnos = objetoDesestructuracion.alumnos
176 | // console.log(nroDeComision)
177 | // console.log(nroDeAlumnos)
178 |
179 | // // Podriamos hacer lo siguiente con desestructuracion:
180 | // const {comision, alumnos, clases, tema} = objetoDesestructuracion
181 | // console.log(comision)
182 | // console.log(alumnos)
183 |
184 |
185 |
186 |
187 | // // Vamos con los arrays (es muy parecido):
188 | // Quiero obtener cada uno de los valores del array por separado
189 | // const numeros = [1, 2, 3]
190 | // // const primero = numeros[0]
191 | // // const segundo = numeros[1]
192 | // // const tercero = numeros[2]
193 |
194 | // // // Con desestructuracion:
195 | // const [primero, segundo, tercero] = numeros
196 | // console.log(primero, segundo, tercero)
197 |
198 |
199 |
200 |
201 |
202 |
203 | // Operador ternario y "template literals" o "template strings"
204 | // const miValor = 20
205 | // if(miValor > 50){
206 | // console.log('mi valor es mayor a 50 y es de: ' + miValor)
207 | // }else{
208 | // console.log('mi valor es menor o igual a 50 y es de: ' + miValor)
209 | // }
210 |
211 | // Veamoslo con operador ternario y template strings:
212 | // const miValor = 49
213 | // console.log(miValor > 50 ? `mi valor es mayor a 50 y es de: ${miValor}` : `mi valor es menor o igual a 50 y es de: ${miValor}`)
214 |
215 | // "mi valor es mayor a 50 y es de: " + miValor
216 | // `mi valor es mayor a 50 y es de: ${miValor}`
217 |
218 | // const estaBuenaClase = false
219 | // const esTrue = true
220 |
221 | // if(esTrue || (estaBuenaClase && miValor > 0)){
222 | // // entra aca
223 | // }else{
224 | // // entra al else
225 | // }
226 |
227 |
228 | // estaBuenaClase ? console.log('Si') : console.log('No')
229 |
230 | // const miCondicion = true
231 | // console.log(miCondicion ? 'es true' : 'es false')
232 |
233 | // Solo decime si es mayor, el resto no me importa:
234 | // miValor > 50 && console.log(`mi valor es mayor a 50 y es de: ${miValor}`)
235 |
236 | // A tener en cuenta:
237 | // const miCarrito = [
238 | // {
239 | // producto: 'Monitor',
240 | // precio: 90000
241 | // },
242 | // {
243 | // producto: 'Teclado',
244 | // precio: 25500
245 | // }
246 | // ]
247 | // Que error tiene la linea de abajo?
248 | // miCarrito && console.log('Hay algo en mi carrito')
249 |
250 |
251 | // Que pasa si el array esta vacio?
252 | const miCarrito = []
253 | // miCarrito && console.log('Hay algo en mi carrito')
254 |
255 | // // En este caso la pregunta podria ser:
256 | // miCarrito.length > 0 ? console.log('Hay algo en mi carrito') : console.log('No hay nada')
257 |
258 | // miCarrito.length > 0 ? 'TRUE' : 'FALSE'
259 |
260 | // if(miCarrito.length > 0){
261 | // console.log('TRUE')
262 | // }else{
263 | // console.log('FALSE')
264 | // }
265 |
266 | // miCarrito.length && 'TRUE'
267 | // if(miCarrito.length > 0){
268 | // console.log('TRUE')
269 | // }
270 |
271 |
272 |
273 |
274 |
275 |
276 | // Ejemplos comunes de Sugar Syntax:
277 | // Sin sugar syntax:
278 | // let i = 0
279 | // i = i + 1
280 | // i = i - 1
281 | // i = i * 4
282 | // i = i / 2
283 | // // Con sugar syntax
284 | // i += 1; // Equivalente a i = i + 1; (Suma)
285 | // i -= 1; // Equivalente a i = i - 1; (Resta)
286 | // i *= 4; // Equivalente a i = i * 4; (Multiplicación)
287 | // i /= 2; // Equivalente a i = i / 2; (División)
288 |
289 | // // Otros ejemplos:
290 | // i++ // Esto suma 1
291 | // i-- // Esto resta 1
292 |
293 |
294 |
295 | // Teoria: // --------------------------------------------------------------------------------------
296 |
297 | // Polyfills:
298 |
299 | // Los polyfills(también conocidos como "shims") son fragmentos de código que se utilizan para proporcionar funcionalidades modernas en navegadores o entornos que no las soportan de forma nativa.En el contexto de React(o cualquier otra biblioteca o framework de JavaScript), los polyfills son especialmente útiles para asegurarse de que tu código funcione en navegadores más antiguos que no admiten ciertas características de JavaScript o APIs del estándar ECMAScript.
300 |
301 | // React, al ser una biblioteca de JavaScript moderna, utiliza muchas características avanzadas de ECMAScript, como "Arrow Functions", "Promises", "Map", "Set", "async/await", etc.Estas características pueden no ser compatibles con versiones antiguas de navegadores como Internet Explorer 11 o versiones más antiguas de navegadores móviles.
302 |
303 | // Los polyfills permiten llenar esas lagunas y proporcionar una implementación compatible para las funciones o características que faltan en el navegador objetivo.De esta manera, puedes escribir código utilizando las últimas características de JavaScript y estar seguro de que funcionará en la mayoría de los navegadores, incluso los más antiguos.
304 |
305 | // Para utilizar polyfills en proyectos de React, hay varias opciones.Algunas de las más comunes son:
306 |
307 | // Babel: Babel es una herramienta popular que se utiliza para transpilar código JavaScript moderno a versiones más compatibles con navegadores antiguos.Junto con Babel, puedes incluir ciertos plugins o presets que incluyan polyfills para las características que necesites.
308 |
309 | // polyfill.io: Es un servicio que permite cargar solo los polyfills necesarios según el navegador del cliente.Simplemente incluyes una URL en tu código y polyfill.io se encarga de servir los polyfills necesarios.
310 |
311 | // core - js: Es una biblioteca que proporciona polyfills para muchas características modernas de JavaScript y es ampliamente utilizada para asegurar la compatibilidad con navegadores antiguos.
312 |
313 | // Es importante destacar que el uso de polyfills puede aumentar el tamaño de los archivos descargados por el cliente y afectar el rendimiento, por lo que es recomendable incluir solo los polyfills necesarios para el soporte de navegadores específicos en lugar de cargar todos los polyfills en todos los navegadores.Además, es importante tener en cuenta que algunos polyfills pueden no ser completamente compatibles con todas las funcionalidades de las características modernas, por lo que siempre es recomendable realizar pruebas exhaustivas en los navegadores objetivo para garantizar que todo funcione correctamente.
314 |
315 | // Instalar libreria de pollyfills:
316 | // npm i core-js
317 | // Importarla en el archivo donde la quiero usar (en este caso es el metodo find() de un array):
318 | // import 'core-js/features/array/find';
319 |
320 |
321 |
322 | // Webpack:
323 |
324 | // Webpack es una herramienta de construcción de módulos para aplicaciones web. Su principal función es tomar diferentes archivos JavaScript, CSS, imágenes y otros recursos, y agruparlos en bundles (paquetes) optimizados para el navegador. De esta manera, se optimiza la carga de la aplicación y se mejora el rendimiento.
325 |
326 | // Webpack también permite la transpilación de código moderno (como ECMAScript 6+) a versiones más antiguas para mejorar la compatibilidad con navegadores más antiguos mediante el uso de loaders. Además, ofrece una amplia gama de plugins para realizar diversas tareas, como la minificación del código, la gestión de assets, la división de bundles, entre otras.
327 |
328 | // En resumen, Webpack es una poderosa herramienta que facilita la construcción y optimización de aplicaciones web al permitir la gestión de dependencias, la transpilación, la creación de bundles y la automatización de tareas, lo que contribuye a mejorar la eficiencia y el rendimiento de los proyectos web.
329 |
330 | // Para profundizar WEBPACK: https://www.youtube.com/watch?v=FMNuTj89RzU&ab_channel=midudev
331 |
332 | // Imaginemos que estás armando un castillo de LEGO.
333 |
334 | // 1. Módulos 🏗️
335 | // En lugar de tener una sola bolsa con todas las piezas mezcladas, tienes bolsas separadas: una para las torres, otra para las murallas, otra para las puertas. Cada bolsa es un módulo que puedes usar cuando lo necesites.
336 |
337 | // 2. Importar y Exportar 📦
338 | // Si necesitas una torre para tu castillo, no tienes que construirla desde cero. Simplemente abres la bolsa de torres (importas el módulo) y la usas en tu castillo. Si tú inventaste una pieza nueva y genial, puedes ponerla en una bolsa aparte (exportarla) para que otros puedan usarla también.
339 |
340 | // 3. Webpack vs. Vite ⚔️
341 | // - Webpack es como si, antes de jugar, abrieras todas las bolsas, juntarás todas las piezas y las metieran en una sola caja. Luego, cuando quieres construir, tienes todo listo, pero tardaste un buen rato en prepararlo.
342 | // - Vite, en cambio, te deja abrir solo las bolsas que necesitas en el momento, sin esperar tanto. Es más rápido y te permite construir sobre la marcha.
343 |
344 | // Así que los módulos son como esas bolsas de piezas organizadas que hacen que todo sea más fácil y ordenado.
--------------------------------------------------------------------------------
/Clase-4/App.jsx:
--------------------------------------------------------------------------------
1 | import './App.css'
2 | import Contador from './components/contador/contador'
3 | // import Saludo from './components/saludo/saludo'
4 | import { Button } from 'antd';
5 | import { SearchOutlined } from '@ant-design/icons';
6 |
7 | // Ejercicio:
8 | // Crear un componente de saludo con un boton y
9 | // cuando le de click al boton aparezca en consola el nombre pasado por props
10 |
11 | function App() {
12 |
13 | return (
14 | <>
15 | {/* Ejercicio 1: */}
16 | {/*