├── Clase 1 └── clase1.js ├── Clase-10 ├── App.jsx └── components │ ├── event │ └── index.jsx │ ├── inputVocales │ └── index.jsx │ ├── prevent │ └── index.jsx │ └── propagation │ ├── index.jsx │ └── styles.module.css ├── Clase-11 ├── App.jsx ├── components │ ├── hijo │ │ └── index.jsx │ └── nieto │ │ ├── index.jsx │ │ └── styles.module.css └── context │ └── shopContext.jsx ├── Clase-12 ├── App.jsx └── components │ ├── loader │ └── index.jsx │ ├── memo │ └── index.jsx │ ├── memoEjemplo │ ├── index.jsx │ └── styles.module.css │ └── miComp │ └── index.jsx ├── Clase-13 ├── App.jsx └── firebase │ └── client.js ├── Clase-14 └── App.jsx ├── Clase-2 └── clase2.txt ├── Clase-3 └── clase3.js ├── Clase-4 ├── App.jsx └── components │ ├── contador │ └── contador.jsx │ └── saludo │ └── saludo.jsx ├── Clase-5 └── index.jsx ├── Clase-6 ├── App.jsx └── components │ ├── cartWidget │ └── cartWidget.jsx │ ├── item │ └── item.jsx │ ├── itemListContainer │ └── itemListContainer.jsx │ └── navBar │ ├── navBar.jsx │ └── styles.module.css ├── Clase-7 └── App.jsx ├── Clase-8 ├── App.jsx ├── components │ ├── container │ │ └── index.jsx │ ├── counter │ │ └── index.jsx │ ├── form │ │ └── index.jsx │ ├── hoc │ │ └── index.jsx │ └── hocCoder │ │ └── index.jsx ├── customHooks │ └── useCounter.jsx └── renderProps │ ├── container │ └── index.jsx │ ├── filter │ └── index.jsx │ └── taskList │ └── index.jsx └── Promises.js /Clase 1/clase1.js: -------------------------------------------------------------------------------- 1 | 2 | // let contarManzanas = function() { return 7;} 3 | // let manzanas = contarManzanas 4 | // console.log(manzanas) 5 | 6 | // let contarManzanas = function() { return 7;} 7 | // let manzanas = contarManzanas() 8 | // console.log(manzanas) 9 | 10 | 11 | // Imperativo // ------------------------------------------------- 12 | 13 | // const arrayDeNumeros = [1, 6, 8, 9, 3, 4] 14 | 15 | // let numerosAltos = [] 16 | // let numerosBajos = [] 17 | // for(let i = 0; i < arrayDeNumeros.length; i++){ 18 | // if(arrayDeNumeros[i] > 4){ 19 | // numerosAltos.push(arrayDeNumeros[i]) 20 | // }else{ 21 | // numerosBajos.push(arrayDeNumeros[i]) 22 | // } 23 | // } 24 | 25 | // return [1, 2, 8].filter(n => n <= 4) 26 | // [1, 2] 27 | 28 | // // console.log(numerosAltos) 29 | // // console.log(numerosBajos) 30 | 31 | // const arrayDeNumeros = [1, 6, 8, 9, 3, 4] 32 | 33 | // const obtenerNumerosBajos = (array) => { 34 | // return array.filter(n => n <= 4) 35 | // } 36 | 37 | // const obtenerNumerosAltos = (array) => { 38 | // return array.filter(n => n > 4) 39 | // } 40 | 41 | // const filtrarNumeros = (array) => { 42 | // const altos = obtenerNumerosAltos(array) 43 | // const bajos = obtenerNumerosBajos(array) 44 | // return {altos, bajos} 45 | // } 46 | 47 | // console.log(filtrarNumeros(arrayDeNumeros)) 48 | 49 | // Expresiones // ------------------------------------------------- 50 | 51 | // console.log(2 + 2) = 4 52 | // console.log(2 + '2') 53 | // console.log('Hola, ' - 'Coders') 54 | // console.log(4 - '2') 55 | 56 | // La programacion imperativa puede existir por si sola, pero la declarativa necesita de la imperativa 57 | 58 | // Creacion de componente: // --------------------------------------- 59 | 60 | const obj = { 61 | nombre: "lucho", 62 | edad: "26" 63 | } 64 | 65 | console.log(obj.nombre) 66 | -------------------------------------------------------------------------------- /Clase-10/App.jsx: -------------------------------------------------------------------------------- 1 | import { useState } from 'react'; 2 | import './App.css'; 3 | // import Listener from './components/event'; 4 | import InputVocales from './components/inputVocales'; 5 | import Prevent from './components/prevent'; 6 | import Propagation from './components/propagation'; 7 | 8 | function App() { 9 | 10 | const [show, setShow] = useState(false) 11 | 12 | return ( 13 |
14 |
15 | 16 | {/* */} 17 | {/* */} 18 | 19 | {/* {show && } 20 | */} 21 |
22 |
23 | ); 24 | 25 | } 26 | 27 | export default App; 28 | -------------------------------------------------------------------------------- /Clase-10/components/event/index.jsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from 'react'; 2 | 3 | const Listener = () => { 4 | 5 | useEffect(() => { 6 | // Función que se ejecutará cuando ocurra el evento 'click' 7 | const handleClick = () => { 8 | console.log('Se hizo click en el elemento'); 9 | }; 10 | 11 | // Agregar el event listener al montar el componente 12 | document.addEventListener('click', handleClick); 13 | 14 | // Remover el event listener al desmontar el componente 15 | return () => { 16 | console.log('Se esta removiendo el event listener'); 17 | document.removeEventListener('click', handleClick); 18 | }; 19 | }, []); // Este efecto se ejecuta solo una vez al montar y desmontar 20 | 21 | return ( 22 |
23 |

Haz clic en cualquier lugar para ver el mensaje en la consola.

24 |
25 | ); 26 | }; 27 | 28 | export default Listener; -------------------------------------------------------------------------------- /Clase-10/components/inputVocales/index.jsx: -------------------------------------------------------------------------------- 1 | import { useState } from "react"; 2 | 3 | const InputVocales = () => { 4 | 5 | 6 | const [inputValue, setInputValue] = useState(''); 7 | 8 | const handleKeyDown = (event) => { 9 | const key = event.key.toLowerCase(); 10 | const vocales = ['a', 'e', 'i', 'o', 'u']; 11 | 12 | if (vocales.includes(key)) { 13 | event.preventDefault(); // Cancela el evento si se presiona una vocal 14 | } 15 | }; 16 | 17 | const handleInputChange = (event) => { 18 | setInputValue(event.target.value); 19 | }; 20 | 21 | return ( 22 |
23 |
24 |

Input sin vocales

25 | 32 |
33 |
34 | ); 35 | } 36 | 37 | export default InputVocales -------------------------------------------------------------------------------- /Clase-10/components/prevent/index.jsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | 3 | const Prevent = () => { 4 | 5 | const handleKeyDown = (event) => { 6 | event.preventDefault(); 7 | console.log(event.key) 8 | }; 9 | 10 | return ( 11 |
12 | console.log(`Contenido: ${e.target.value}`)} 16 | /> 17 |
18 | ); 19 | }; 20 | 21 | export default Prevent; -------------------------------------------------------------------------------- /Clase-10/components/propagation/index.jsx: -------------------------------------------------------------------------------- 1 | import styles from './styles.module.css' 2 | 3 | const Propagation = () => { 4 | 5 | return( 6 |
console.log('click en el div')}> 7 | 15 |
16 | ) 17 | } 18 | 19 | export default Propagation -------------------------------------------------------------------------------- /Clase-10/components/propagation/styles.module.css: -------------------------------------------------------------------------------- 1 | .container{ 2 | width: 200px; 3 | height: 100px; 4 | background-color: aqua; 5 | cursor: pointer; 6 | } -------------------------------------------------------------------------------- /Clase-11/App.jsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useContext, useState, createContext } from "react"; 2 | import './App.css'; 3 | import Hijo from './components/hijo'; 4 | import { ShopComponentContext } from './context/shopContext'; 5 | 6 | const mockProductos = [{ 7 | titulo: 'Remera', 8 | precio: 6000, 9 | descripcion: 'lorem ipsum lorem ipsum' 10 | }, 11 | { 12 | titulo: 'Pantalon', 13 | precio: 12000, 14 | descripcion: 'lorem ipsum lorem ipsum' 15 | }, 16 | { 17 | titulo: 'Buzo', 18 | precio: 18000, 19 | descripcion: 'lorem ipsum lorem ipsum' 20 | }] 21 | 22 | 23 | function App() { 24 | 25 | return ( 26 |
27 |
28 | 29 | 30 | 31 |
32 |
33 | ); 34 | } 35 | 36 | export default App; 37 | -------------------------------------------------------------------------------- /Clase-11/components/hijo/index.jsx: -------------------------------------------------------------------------------- 1 | import { useContext } from 'react' 2 | import Nieto from '../nieto' 3 | 4 | const Hijo = () => { 5 | 6 | return( 7 |
8 | 9 |
10 | ) 11 | } 12 | 13 | export default Hijo -------------------------------------------------------------------------------- /Clase-11/components/nieto/index.jsx: -------------------------------------------------------------------------------- 1 | import React, {useContext, useState} from 'react'; 2 | import styles from './styles.module.css' 3 | import { ShopContext } from '../../context/shopContext'; 4 | 5 | const Nieto = () => { 6 | 7 | const { productos } = useContext(ShopContext) 8 | 9 | return ( 10 |
11 | {/* */} 12 | {productos.map((prod, index) => { 13 | return( 14 |
15 |

{prod.titulo}

16 |

{prod.descripcion}

17 |

$ {prod.precio}

18 |
19 | ) 20 | })} 21 |
22 | ); 23 | }; 24 | 25 | export default Nieto; -------------------------------------------------------------------------------- /Clase-11/components/nieto/styles.module.css: -------------------------------------------------------------------------------- 1 | .card{ 2 | width: 200px; 3 | height: 120px; 4 | background-color: rgb(60, 71, 71); 5 | cursor: pointer; 6 | border-radius: 10px; 7 | padding: 6px; 8 | } 9 | 10 | .container{ 11 | display: flex; 12 | justify-content: space-around; 13 | width: 700px; 14 | flex-wrap: wrap; 15 | } -------------------------------------------------------------------------------- /Clase-11/context/shopContext.jsx: -------------------------------------------------------------------------------- 1 | import { createContext } from "react"; 2 | import { useState, useEffect } from "react"; 3 | 4 | const mockProductos = [{ 5 | titulo: 'Remera', 6 | precio: 6000, 7 | descripcion: 'lorem ipsum lorem ipsum' 8 | }, 9 | { 10 | titulo: 'Pantalon', 11 | precio: 12000, 12 | descripcion: 'lorem ipsum lorem ipsum' 13 | }, 14 | { 15 | titulo: 'Buzo', 16 | precio: 18000, 17 | descripcion: 'lorem ipsum lorem ipsum' 18 | }] 19 | 20 | 21 | // Creamos el contexto con createContext 22 | export const ShopContext = createContext(); 23 | 24 | 25 | // Creamos un componente para nuestro contexto 26 | export const ShopComponentContext = ({children}) => { 27 | 28 | const [productos, setProductos] = useState([]) 29 | 30 | const limpiarProductos = () =>{ 31 | setProductos([]) 32 | } 33 | 34 | useEffect(() => { 35 | setProductos(mockProductos) 36 | }, []) 37 | 38 | return 39 | {children} 40 | 41 | } -------------------------------------------------------------------------------- /Clase-12/App.jsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react"; 2 | import './App.css'; 3 | // import MiComponente from './components/memo' 4 | import Contador from "./components/memoEjemplo"; 5 | import Loader from "./components/loader"; 6 | 7 | function App() { 8 | 9 | const [contador, setContador] = useState(0) 10 | const [contador2, setContador2] = useState(0) 11 | 12 | const [load, setLoad] = useState(true) 13 | 14 | // Return temprano: 15 | 16 | // if(miCondicion){ 17 | // return ( 18 | // <> 19 | //

Se cumplio mi condicion

20 | // 21 | // ) 22 | // } 23 | 24 | return ( 25 |
26 |
27 | 28 | 29 | 30 | {/* // Renders condicionales */} 31 | 32 | {/* {loader &&

Cargando

} 33 | {!loader &&

Bienvenidos

} */} 34 | {/* {loader ?

Cargando

:

Bienvenidos

} */} 35 | 36 | 37 | 38 | {/* 39 | */} 40 | 41 |
42 |
43 | ); 44 | } 45 | 46 | 47 | 48 | export default App; 49 | -------------------------------------------------------------------------------- /Clase-12/components/loader/index.jsx: -------------------------------------------------------------------------------- 1 | const Loader = ({loading, setLoad}) => { 2 | return( 3 | <> 4 | {loading &&

Hola soy el cargando del componente nuevo

} 5 | 6 | 7 | ) 8 | } 9 | 10 | export default Loader -------------------------------------------------------------------------------- /Clase-12/components/memo/index.jsx: -------------------------------------------------------------------------------- 1 | import React, { memo } from 'react'; 2 | 3 | // Definimos nuestro componente funcional 4 | const MiComponente = ({ datos }) => { 5 | console.log(datos) 6 | return ( 7 |
8 |

{datos}

9 |
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 |
11 |

{title}

12 |

Contador: {cont}

13 | 14 | 15 |
16 | ); 17 | }; 18 | 19 | // Usamos memo para optimizar el componente 20 | export default memo(Contador); -------------------------------------------------------------------------------- /Clase-12/components/memoEjemplo/styles.module.css: -------------------------------------------------------------------------------- 1 | .card{ 2 | border: solid 1px black; 3 | margin-top: 50px; 4 | padding: 12px; 5 | } -------------------------------------------------------------------------------- /Clase-12/components/miComp/index.jsx: -------------------------------------------------------------------------------- 1 | const MiComp = ({title}) => { 2 | console.log(`Soy el componente hijo de ${title}`) 3 | return( 4 |

Soy el componente hijo de {title}

5 | ) 6 | } 7 | 8 | export default MiComp -------------------------------------------------------------------------------- /Clase-13/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 } from 'firebase/firestore' 8 | 9 | 10 | function App() { 11 | // Traer toda la data de una coleccion de firebase: 12 | const productsRef = collection(db, "products") 13 | 14 | const getProducts = async () => { 15 | const data = await getDocs(productsRef) 16 | const dataFiltrada = data.docs.map((doc) => ( {...doc.data(), id: doc.id} )) 17 | console.log(dataFiltrada) 18 | } 19 | 20 | // Traer toda la data de una coleccion de firebase con filtros: 21 | // const productsRefFilter = query( 22 | // collection(db, "products"), 23 | // where("categoryId", "==", "pantalones"), 24 | // where("stock", "<", 10), 25 | // limit(10) 26 | // ) 27 | 28 | 29 | // Para obtener un documento especifico: 30 | // const productRef = doc(db, "products", "RDIjhYFRE455GU9sKujt") 31 | // const getProduct = () => { 32 | // getDoc(productRef).then((snapshot => { 33 | // if(snapshot.exists()){ 34 | // // console.log(snapshot) 35 | // console.log( { id: snapshot.id, ...snapshot.data() } ) 36 | // } 37 | // })) 38 | // } 39 | 40 | useEffect(() => { 41 | // getProduct() 42 | getProducts() 43 | }, []); 44 | 45 | 46 | 47 | return ( 48 |
49 |
50 | 51 |
52 |
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 | {/*

Titulo

17 | 18 | */} 19 | 20 | 21 | {/*Ejercicio 2: */} 22 | 23 | 24 | 25 | 26 | {/* Componente de libreria AntDesign */} 27 | 30 | 31 | ) 32 | } 33 | 34 | export default App 35 | -------------------------------------------------------------------------------- /Clase-4/components/contador/contador.jsx: -------------------------------------------------------------------------------- 1 | import { useState } from "react" 2 | 3 | // Ejercicio: 4 | // 1) Implementar un boton nuevo que lo que haga es resetear el valor a 0 5 | // 2) Validar que el monto no quede en valor 0 o negativo 6 | 7 | 8 | const Contador = () => { 9 | 10 | const [contador, setContador] = useState(1) 11 | 12 | // let contador = 0 13 | const suma = () => { 14 | setContador(contador + 1) 15 | // contador += 1 16 | // console.log(contador) 17 | } 18 | 19 | const resta = () => { 20 | // if(contador > 1){ 21 | // setContador(contador - 1) 22 | // } 23 | 24 | contador > 1 && setContador(contador - 1) 25 | 26 | // contador -= 1 27 | // console.log(contador) 28 | } 29 | 30 | const reset = () => { 31 | setContador(1) 32 | } 33 | 34 | return( 35 | <> 36 | 37 |

{contador}

38 | 39 | 40 | 41 | ) 42 | } 43 | 44 | export default Contador -------------------------------------------------------------------------------- /Clase-4/components/saludo/saludo.jsx: -------------------------------------------------------------------------------- 1 | const Saludo = ({nombre}) => { 2 | 3 | // const click = () => { 4 | // console.log(nombre) 5 | // } 6 | 7 | return( 8 | <> 9 | 10 | 11 | ) 12 | } 13 | 14 | export default Saludo -------------------------------------------------------------------------------- /Clase-5/index.jsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react" 2 | 3 | const EffectComponent = () => { 4 | 5 | const [contador, setContador] = useState(0) 6 | const [nombre, setNombre] = useState('NombreEjemplo') 7 | 8 | // useEffect(() => { 9 | // console.log('Soy el useEffect que se ejecuta cuando el componente se monta por primera vez y cuando alguno de los estados se modifique') 10 | // }) 11 | 12 | // useEffect(() => { 13 | // console.log('Soy el useEffect que se ejecuta solo cuando el componente se monta') 14 | // }, []) 15 | 16 | // useEffect(() => { 17 | // console.log('soy el useEffect que se ejecuta cuando el componente se monta y cuando el estado contador cambia') 18 | // // IMPORTANTE: Si el estado nombre cambia no va a afectar y no se va a ejecutar este useEffect!!! 19 | // }, [contador]) 20 | 21 | const sumar = () => { 22 | setContador(contador + 1) 23 | } 24 | 25 | const cambiarNombre = () => { 26 | setNombre('Juan') 27 | } 28 | 29 | return( 30 | <> 31 |

Contador: {contador}

32 | 33 |

Nombre: {nombre}

34 | 35 | 36 | 37 | ) 38 | } 39 | 40 | export default EffectComponent -------------------------------------------------------------------------------- /Clase-6/App.jsx: -------------------------------------------------------------------------------- 1 | import { useState } from 'react' 2 | import './App.css' 3 | import NavBar from './components/navBar/navBar' 4 | import ItemListContainer from './components/itemListContainer/itemListContainer' 5 | // import Contador from './components/contador/contador.jsx' 6 | import { Button } from 'antd' 7 | 8 | function App() { 9 | const [mostrar, setMostrar] = useState(true) 10 | 11 | return ( 12 | <> 13 | 14 | {mostrar && } 15 | 16 | 17 | ) 18 | } 19 | 20 | export default App 21 | -------------------------------------------------------------------------------- /Clase-6/components/cartWidget/cartWidget.jsx: -------------------------------------------------------------------------------- 1 | import { Avatar, Badge } from 'antd'; 2 | import {ShoppingCartOutlined} from '@ant-design/icons'; 3 | const CartWidget = () => { 4 | return ( 5 | <> 6 | 7 | } /> 8 | 9 | 10 | ) 11 | } 12 | 13 | export default CartWidget -------------------------------------------------------------------------------- /Clase-6/components/item/item.jsx: -------------------------------------------------------------------------------- 1 | const Item = ({producto}) => { 2 | return( 3 |
4 |

{producto.name}

5 |

{producto.precio}

6 |
7 | ) 8 | } 9 | 10 | export default Item -------------------------------------------------------------------------------- /Clase-6/components/itemListContainer/itemListContainer.jsx: -------------------------------------------------------------------------------- 1 | import { Button } from "antd" 2 | import { useEffect, useRef, useState } from "react" 3 | import {Spin} from 'antd'; 4 | import Item from "../item/item"; 5 | const ItemListContainer = ({greeting}) => { 6 | const [products, setProducts] = useState([]) 7 | // Crear una promise que devuelva un array de productos con el siguiente formato: 8 | // {name: "producto1", precio: 2000, id: 1}. IMPORTANTE: El ID no puede repetirse 9 | // Simular tiempo de espera 10 | 11 | // Cuando el componente se monte hacer la peticion a la promise, guardar la data y mostrarla. 12 | // NOTA: Mostrar nombre y precio 13 | 14 | // 1) Crear la Promise 15 | const promesa = new Promise((resolve, reject) => { 16 | const productosArray = [ 17 | {name: "Remera", precio: 20000, id: 1}, 18 | {name: "Pantalon", precio: 12500, id: 2}, 19 | {name: "Buzo", precio: 35000, id: 3}, 20 | {name: "Campera", precio: 55500, id: 4} 21 | ] 22 | 23 | setTimeout(() => { 24 | productosArray.length > 0 ? resolve(productosArray) : reject({data: [], message: "No hay productos"}) 25 | }, 5000) 26 | }) 27 | 28 | 29 | // 2) Llamar a la promise y guardar su resultado... Acuerdense: 30 | // QUE ESTAN TRABAJANDO CON REACT. 31 | useEffect(() => { 32 | promesa 33 | .then(res => { 34 | console.log(res) 35 | setProducts(res) 36 | }) 37 | .catch(error => console.error(error.message)) 38 | }, []) 39 | 40 | 41 | return( 42 | <> 43 |

{greeting}

44 | {/* 3) Recorrer el array de productos y mostrar nombre y precio */} 45 | {products.length > 0 ? ( 46 | <> 47 | {products.map((prod, index) => )} 48 | 49 | ) : ( 50 | 51 | )} 52 | <> 53 | 54 | 55 | ) 56 | } 57 | 58 | export default ItemListContainer -------------------------------------------------------------------------------- /Clase-6/components/navBar/navBar.jsx: -------------------------------------------------------------------------------- 1 | import { DownOutlined } from '@ant-design/icons'; 2 | import { Dropdown, Space } from 'antd'; 3 | import CartWidget from '../cartWidget/cartWidget'; 4 | import styles from './styles.module.css' 5 | const items = [ 6 | { 7 | label: ( 8 | 9 | 1st menu item 10 | 11 | ), 12 | key: '0', 13 | }, 14 | { 15 | label: ( 16 | 17 | 2nd menu item 18 | 19 | ), 20 | key: '1', 21 | }, 22 | { 23 | type: 'divider', 24 | }, 25 | { 26 | label: '3rd menu item(disabled)', 27 | key: '3', 28 | disabled: true, 29 | }, 30 | ]; 31 | 32 | const NavBar = () => { 33 | return ( 34 | <> 35 |

Soy el navbar

36 | 37 | 38 | ) 39 | } 40 | 41 | export default NavBar -------------------------------------------------------------------------------- /Clase-6/components/navBar/styles.module.css: -------------------------------------------------------------------------------- 1 | .navbar{ 2 | background-color: red; 3 | } -------------------------------------------------------------------------------- /Clase-7/App.jsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from 'react'; 2 | import './App.css'; 3 | import ListProductos from './components/listProductos' 4 | 5 | // https://fakestoreapi.com/docs 6 | 7 | function App() { 8 | 9 | const [cargando, setCargando] = useState(true) 10 | const [productos, setProductos] = useState([]) 11 | const [categories, setCategories] = useState([]) 12 | const [categorySelected, setCategorySelected] = useState() 13 | const [cart, setCart] = useState([]) 14 | 15 | 16 | useEffect(() => { 17 | fetch('https://fakestoreapi.com/products') 18 | .then(res => res.json()) 19 | .then(data => { 20 | console.log(data) 21 | setProductos(data) 22 | }) 23 | .catch(e => console.error(e)) 24 | .finally(() => setCargando(false)) 25 | 26 | fetch('https://fakestoreapi.com/products/categories') 27 | .then(res => res.json()) 28 | .then(data => setCategories(data)) 29 | .catch(e => console.error(e)) 30 | }, []) 31 | 32 | useEffect(() => { 33 | if(categorySelected){ 34 | fetch(`https://fakestoreapi.com/products/category/${categorySelected}`) 35 | .then(res => res.json()) 36 | .then(data => { 37 | console.log(data) 38 | setProductos(data) 39 | }) 40 | .catch(e => console.error(e)) 41 | .finally(() => setCargando(false)) 42 | } 43 | }, [categorySelected]) 44 | 45 | const getByCategory = (cat) => { 46 | setCargando(true) 47 | setCategorySelected(cat) 48 | } 49 | 50 | return ( 51 |
52 |
53 |

Mi Ecommerce en React - Cart: {cart.length}

54 |
55 |
56 | {categories?.map(cat => { 57 | // mis botones de categorias que cada onClick ejecute getByCategory('MiCategoria') 58 | })} 59 |
60 | {cargando ? ( 61 |

Cargando productos...

62 | ) : ( 63 | // Mi map o componente con map de productos 64 | )} 65 |
66 |
67 |
68 | ); 69 | } 70 | 71 | export default App; 72 | 73 | 74 | 75 | // Componente que me devuelva los items con una llamada fetch 76 | // y una lista de botones que me permita filtrar por categorias -------------------------------------------------------------------------------- /Clase-8/App.jsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from 'react'; 2 | import './App.css'; 3 | import useCounter from './customHooks/useCounter'; 4 | import { MiComponente, MiComponenteConLogica } from './components/hoc'; 5 | import Container from './components/container'; 6 | import ContainerProps from './renderProps/container'; 7 | import Counter from './components/counter'; 8 | 9 | // const Box = ({saludo, saludo2, children}) => { 10 | // console.log(children) 11 | // return( 12 | // <> 13 | // {children} 14 | // 15 | // ) 16 | // } 17 | 18 | // const ComponenteChildren = () => { 19 | 20 | // return( 21 | //

Soy el componente children

22 | // ) 23 | // } 24 | 25 | function App() { 26 | // const [stock, setStock] = useState(20) 27 | // const [miTexto, setMiTexto] = useState('Hola como estas?') 28 | // const [carrito, setCarrito] = useState([]) 29 | 30 | // const {contador, decrementar, aumentar, resetear} = useCounter(1, stock) 31 | 32 | 33 | // const stockContador = useCounter(10, stock) 34 | // const cantidadAgregada = useCounter(1, stock) 35 | 36 | // const agregar = (cantidad) => { 37 | // setCarrito([...carrito, {producto: "Remera negra oversize", cantidad: cantidad}]) 38 | // cantidadAgregada.resetear() 39 | // stockContador.decrementarPorValor(cantidad) 40 | // } 41 | 42 | return ( 43 |
44 |
45 | {/* 46 | 47 | */} 48 | 49 | 50 | {/*
51 | Mi contador de stock: {stockContador.contador} 52 |
53 | 54 | 55 |
56 | 57 |
58 | 59 |
60 | Producto: Remera negra oversize 61 |
62 |

63 | Stock: {stock} 64 |

65 |

66 | Cantidad: {cantidadAgregada.contador} 67 |

68 | 69 | 70 |
71 | 72 |
*/} 73 | 74 | 75 | 76 | {/*
77 | Producto: Remera negra oversize 78 |
79 | Stock: {stock} 80 | Cantidad: 1 81 | 82 | 83 |
84 | 85 |
*/} 86 | 87 | 88 | {/* ----------------------------- HOC ------------------------------------*/} 89 | {/* */} 90 | {/* */} 91 | 92 | {/* */} 93 | 94 | 95 | {/* --------------------------- RenderProps -------------------------------- */} 96 | {/* */} 97 |
98 |
99 | ); 100 | } 101 | 102 | export default App; 103 | -------------------------------------------------------------------------------- /Clase-8/components/container/index.jsx: -------------------------------------------------------------------------------- 1 | import { useState } from "react"; 2 | import withFormValidation from "../hocCoder"; 3 | import Form from "../form"; 4 | 5 | const FormWithValidation = withFormValidation(Form) 6 | 7 | const Container = () => { 8 | const [formData, setFormData] = useState({ 9 | nombre: '', 10 | email: '' 11 | }) 12 | 13 | const handleChange = (event) => { 14 | setFormData({ 15 | ...formData, 16 | [event.target.name]: event.target.value 17 | }) 18 | } 19 | 20 | return( 21 |
22 | 23 |
24 | ) 25 | } 26 | 27 | export default Container -------------------------------------------------------------------------------- /Clase-8/components/counter/index.jsx: -------------------------------------------------------------------------------- 1 | import { useState } from "react" 2 | 3 | const Counter = ({children}) => { 4 | 5 | const [contador, setContador] = useState(0) 6 | 7 | console.log(children) 8 | const increment = () => { 9 | setContador(prev => prev + 1) 10 | } 11 | 12 | const decrement = () => { 13 | setContador(prev => prev - 1) 14 | } 15 | 16 | const reset = () => { 17 | setContador(0) 18 | } 19 | 20 | return( 21 | <> 22 |

Contador: {contador}

23 | 24 | 25 | 26 | 27 | ) 28 | } 29 | 30 | export default Counter -------------------------------------------------------------------------------- /Clase-8/components/form/index.jsx: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | 3 | const Form = ({ formData, errors, validateForm, onChange }) => { 4 | 5 | const handleSubmit = (event) => { 6 | event.preventDefault() 7 | validateForm && validateForm() 8 | } 9 | 10 | return( 11 |
12 |
13 | 14 | onChange(e)}/> 15 | {errors && errors.nombre &&
{errors.nombre}
} 16 |
17 | 18 |
19 | 20 | onChange(e)}/> 21 | {errors && errors.email &&
{errors.email}
} 22 |
23 | 24 |
25 | ) 26 | } 27 | 28 | export default Form -------------------------------------------------------------------------------- /Clase-8/components/hoc/index.jsx: -------------------------------------------------------------------------------- 1 | import { useEffect } from "react" 2 | 3 | export const ComponenteUno = () => { 4 | return( 5 |
Mira la consola!
6 | ) 7 | } 8 | 9 | 10 | 11 | 12 | 13 | 14 | export const withConsoleLog = (Component) => { 15 | 16 | 17 | 18 | const ComponenteMejorado = () => { 19 | 20 | useEffect(() => { 21 | console.log('Mensaje desde el withConsoleLog') 22 | }, []) 23 | 24 | return 25 | } 26 | 27 | 28 | 29 | return ComponenteMejorado 30 | } 31 | 32 | 33 | 34 | 35 | 36 | export const MiComponenteConLogica = withConsoleLog(ComponenteUno) -------------------------------------------------------------------------------- /Clase-8/components/hocCoder/index.jsx: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import { useState } from "react" 3 | 4 | const withFormValidation = (WrappedComponent) => { 5 | 6 | const WithFormValidation = (props) => { 7 | const [errors, setErrors] = useState({}) 8 | 9 | const validateForm = () => { 10 | let newErrors = {} 11 | 12 | if(!props.formData.nombre){ 13 | newErrors = {nombre: 'el nombre es requerido'} 14 | } 15 | 16 | if(!props.formData.email){ 17 | newErrors = {email: 'el email es requerido'} 18 | } 19 | setErrors(newErrors) 20 | } 21 | 22 | return( 23 | 28 | ) 29 | } 30 | 31 | return WithFormValidation 32 | } 33 | 34 | export default withFormValidation -------------------------------------------------------------------------------- /Clase-8/customHooks/useCounter.jsx: -------------------------------------------------------------------------------- 1 | import { useState } from "react" 2 | 3 | // Arranca con use en minuscula 4 | const useCounter = (valorInicial, max) => { 5 | const [contador, setContador] = useState(valorInicial) 6 | 7 | const aumentar = () => { 8 | contador < max && setContador(prev => prev + 1) 9 | } 10 | 11 | const decrementar = () => { 12 | contador > 1 && setContador(prev => prev - 1) 13 | } 14 | 15 | const decrementarPorValor = (cantidad) => { 16 | contador >= cantidad && setContador(prev => prev - cantidad) 17 | } 18 | 19 | const resetear = () => { 20 | setContador(valorInicial) 21 | } 22 | 23 | return { 24 | contador, 25 | aumentar, 26 | decrementar, 27 | resetear, 28 | decrementarPorValor 29 | } 30 | } 31 | 32 | export default useCounter -------------------------------------------------------------------------------- /Clase-8/renderProps/container/index.jsx: -------------------------------------------------------------------------------- 1 | import Filter from "../filter" 2 | import TaskList from "../taskList" 3 | 4 | const ContainerProps = () => { 5 | const tasks = [ 6 | { id: 1, title: "Comprar leche", completed: true}, 7 | { id: 2, title: "Ir al gimnasio", completed: false}, 8 | { id: 3, title: "Cocinar cena", completed: false} 9 | ] 10 | 11 | return( 12 |
13 | 14 | {(filterState, handleFilterChange) => ( 15 |
16 | 17 | 22 | 23 | filterState === "completed" ? task.completed : !task.completed) 27 | } 28 | /> 29 |
30 | )} 31 |
32 |
33 | ) 34 | } 35 | 36 | export default ContainerProps -------------------------------------------------------------------------------- /Clase-8/renderProps/filter/index.jsx: -------------------------------------------------------------------------------- 1 | import { useState } from "react" 2 | 3 | const Filter = ({children}) => { 4 | const [filterState, setFilterState] = useState('all') 5 | 6 | const handleFilterChange = (event) => { 7 | setFilterState(event.target.value) 8 | } 9 | 10 | return children(filterState, handleFilterChange) 11 | } 12 | 13 | export default Filter -------------------------------------------------------------------------------- /Clase-8/renderProps/taskList/index.jsx: -------------------------------------------------------------------------------- 1 | const TaskList = ({ tasks }) => { 2 | return( 3 |
    4 | {tasks.map((task) => { 5 | return( 6 |
  • {task.title}
  • 7 | ) 8 | })} 9 |
10 | ) 11 | } 12 | 13 | export default TaskList -------------------------------------------------------------------------------- /Promises.js: -------------------------------------------------------------------------------- 1 | // Promises 2 | 3 | // const myPromise = new Promise((resolve, reject) => { 4 | // // Simulamos una operación asincrónica 5 | // setTimeout(() => { 6 | // reject('REJECT: Operacion rechazada'); 7 | // resolve('RESOLVE: Me resolvi con exito'); 8 | // }, 2000); // Simulamos un tiempo de espera de 2 segundos 9 | // }); 10 | 11 | // console.log(myPromise); // Output: Promise { } 12 | 13 | // myPromise 14 | // .then(res => console.log(res)) // Output: RESOLVE: 'Me resolvi con exito' 15 | // .catch(error => console.error(error)) // Output: 'REJECT: Operacion rechazada' 16 | // .finally(() => console.log('Me termine de resolver con o sin errores')) 17 | 18 | 19 | 20 | // EJEMPLO ASYNC AWAIT 21 | 22 | // const getPromise = async () => { 23 | // try{ 24 | // console.log(await myPromise) 25 | // }catch (error){ 26 | // console.error(error) 27 | // }finally { 28 | // console.log('Entro al finally') 29 | // } 30 | // } 31 | 32 | // getPromise() 33 | 34 | 35 | // Ejercicio 1: 36 | 37 | // Crear una promise donde tengamos un numero random (lo pueden poner ustedes fijo) 38 | // Y si ese numero es mayor a 50 entre al resolve con un msj de "El numero es mayor a 50" 39 | // Y si ese numero es menor o igual a 50 entre al reject con un msj de 40 | // "El numero es menor o igual a 50" 41 | 42 | // const myPromise = new Promise((resolve, reject) => { 43 | // }); 44 | 45 | 46 | // Respuesta: 47 | 48 | // const miPromise = new Promise((resolve, reject) => { 49 | // const num = 44; 50 | // num > 50 ? resolve("El número es mayor a 50") : reject("El número es menor o igual a 50"); 51 | // }); 52 | 53 | // miPromise 54 | // .then((resultado) => { 55 | // console.log(resultado); 56 | // }) 57 | // .catch((error) => { 58 | // console.error(error); 59 | // }) 60 | // .finally(() => console.log('Terminó')); 61 | 62 | // MAP 63 | 64 | 65 | // const numbers = [1, 2, 3, 4, 5]; 66 | 67 | // const doubledNumbers = numbers.map((number, index) => { 68 | // console.log(index) 69 | // return number * 2; 70 | // }); 71 | 72 | // console.log(numbers) // El map no modifica el array original sino que crea uno nuevo 73 | // console.log(doubledNumbers); // Output: [2, 4, 6, 8, 10] 74 | 75 | 76 | // Ejercicio 2: 77 | 78 | // Crear una funcion donde a partir de un array de nombres me devuelva en la consola: 79 | // "Hola, (nombre correspondiente)" 80 | // Array: [Guido, Guille, Ale, Chiara, Cami] 81 | 82 | const nombres= ["Guido", "Guille", "Ale", "Chiara", "Cami"] 83 | 84 | nombres.map((nombre) => console.log(`Hola, ${nombre}`)); 85 | 86 | 87 | 88 | // // Rta: 89 | // const nombres = ["Guido", "Guille", "Ale", "Chiara", "Cami"] 90 | 91 | // const saludar = (arrayDeNombres) => { 92 | // return arrayDeNombres.map(n => console.log(`Hola, ${n}`)) 93 | // } 94 | 95 | // saludar(nombres) 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | // Ejercicio bonus // 114 | 115 | // Realizar una funcion que me devuelva el listado de Usuarios despues de 3 segundos (resolve) 116 | // con then, catch y finally 117 | // ACLARACION: (El finally me debe mostrar en consola el mensaje: 118 | // 'Termine de resolver o rechazar la solicitud') 119 | 120 | // BONUS: Lo mismo pero con try catch 121 | 122 | // { id: 1, name: 'Juan', age: 25 }, 123 | // { id: 2, name: 'Micaela', age: 18 }, 124 | // { id: 3, name: 'Guido', age: 14 }, 125 | // { id: 4, name: 'Flor', age: 15 }, 126 | // { id: 5, name: 'Nicolas', age: 32 } 127 | 128 | 129 | 130 | 131 | // Estructura del ejercicio: 132 | 133 | // const getUsers = () => { 134 | // return new Promise((resolve, reject) => { 135 | // setTimeout(() => { 136 | // // Ingresar las respuestas de resolve y reject: 137 | // const users = [ 138 | // { id: 1, name: 'Juan', age: 25 }, 139 | // { id: 2, name: 'Micaela', age: 18 }, 140 | // { id: 3, name: 'Guido', age: 14 }, 141 | // { id: 4, name: 'Flor', age: 15 }, 142 | // { id: 5, name: 'Nicolas', age: 32 } 143 | // ] 144 | // users.length > 0 ? resolve(users) : reject('Error no hay usuarios') 145 | // }, 3000); 146 | // }) 147 | // } 148 | 149 | 150 | 151 | // // Llamar a la funcion usando .then y .catch 152 | // getUsers() 153 | // .then(res => console.log(res)) // TABLE 154 | // .catch(e => console.error(e)) 155 | // .finally(() => console.log('Termine de resolver o rechazar la solicitud')) 156 | 157 | // // Con async / await || try catch 158 | // const llameUsuarios = async () => { 159 | // try{ 160 | // const res = await getUsers() 161 | // console.log(res) 162 | // }catch(e) { 163 | // console.log('Error: ' + e) 164 | // } finally { 165 | // console.log('Termine de resolver o rechazar la solicitud') 166 | // } 167 | // } 168 | 169 | // llameUsuarios() 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | // const getUsersData = new Promise((resolve, reject) => { 178 | // // Simulamos una petición asincrónica para obtener los datos del usuario 179 | // setTimeout(() => { 180 | // const usersData = [ 181 | // { id: 1, name: 'Juan', age: 25 }, 182 | // { id: 2, name: 'Micaela', age: 18 }, 183 | // { id: 3, name: 'Guido', age: 14 }, 184 | // { id: 4, name: 'Flor', age: 15 }, 185 | // { id: 5, name: 'Nicolas', age: 32 } 186 | // ]; 187 | // if (usersData) { 188 | // resolve(usersData); // Si se resuelve con éxito, devolvemos los datos del usuario 189 | // } else { 190 | // reject('No se pudo obtener los datos del usuario'); // Si falla, rechazamos la Promise con un mensaje de error 191 | // } 192 | // }, 3000); // Simulamos un tiempo de espera de 3 segundos 193 | // }) 194 | 195 | // getUsersData() 196 | // .then(usersData => { 197 | // usersData.map(user => { 198 | // if(user.age >= 16){ 199 | // console.log(user) 200 | // } 201 | // }) 202 | // }) 203 | // .catch(error => { 204 | // console.error(error); // Si la Promise es rechazada, imprimimos un mensaje de error en la consola 205 | // }); 206 | 207 | 208 | 209 | 210 | // Dado un array de numeros crear una funcion que devuelva el valor mas bajo 211 | // y el mas alto haciendo un solo loop. 212 | // const arrayOfNumber = [9, 4, 10, 20, 555, 2, 56, 99] 213 | 214 | 215 | 216 | 217 | 218 | 219 | // function getMinorAndMajor(numbers){ 220 | // let minor = numbers[0]; 221 | // let major = numbers[0]; 222 | // for(let i = 0; i < numbers.length; i++){ 223 | // if(numbers[i] > major){ 224 | // major = numbers[i] 225 | // } 226 | 227 | // if(numbers[i] < minor){ 228 | // minor = numbers[i] 229 | // } 230 | // } 231 | 232 | // return [minor, major] 233 | // } 234 | 235 | // console.log(getMinorAndMajor(arrayOfNumber)) 236 | 237 | const arrayOfNumber = [9, 4, 10, 20, 555, 2, 56, 99] 238 | 239 | // const getMinorAndMajor = (numbers) => { 240 | // let minor, major 241 | // numbers.forEach((number, index) => { 242 | // !index && (minor = number, major = number) 243 | // minor > number && (minor = number) 244 | // major < number && (major = number) 245 | // }); 246 | // return [minor, major] 247 | // } 248 | 249 | 250 | // function getMinorAndMajor(numbers) { 251 | // if (numbers.length === 0) { 252 | // return { minor: undefined, major: undefined }; 253 | // } 254 | // let min = numbers[0]; 255 | // let max = numbers[0]; 256 | // for (const number of numbers) { 257 | // if (number < min) { 258 | // min = number; 259 | // } 260 | // if (number > max) { 261 | // max = number; 262 | // } 263 | // } 264 | // return { minor: min, major: max }; 265 | // } 266 | 267 | 268 | 269 | // function getMinorAndMajor(numbers){ 270 | // let min = Math.min(...numbers) 271 | // let max = Math.max(...numbers) 272 | // console.log(min) 273 | // console.log(max) 274 | // } 275 | 276 | // console.log(getMinorAndMajor(arrayOfNumber)) 277 | 278 | // function getMinorAndMajor(numbers){ 279 | 280 | // let min = 0 281 | // let max = 0 282 | 283 | // for(i=0; imax){ 292 | // max = numbers[i] 293 | // } 294 | // } 295 | // } 296 | // console.log(min) 297 | // console.log(max) 298 | // } 299 | 300 | // console.log(getMinorAndMajor(arrayOfNumber)) --------------------------------------------------------------------------------