From e0aa83920d23d5f301bbf859255d595dd78194e9 Mon Sep 17 00:00:00 2001 From: Jairiana de Jesus Date: Wed, 13 Dec 2023 18:29:34 -0300 Subject: [PATCH 01/19] Componentes y Elementos --- src/App.js | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/src/App.js b/src/App.js index 952c8f1fd..f3ac77f91 100644 --- a/src/App.js +++ b/src/App.js @@ -2,8 +2,19 @@ import logo from './platzi.webp'; import './App.css'; function App() { - return ( + return ( // a partir de aqui no estamos incorporando html, sino JSX
+ + {/* ¿ Cómo llamo a un componente? Escribiendo su nombre con la siguiente sintáxis < Componente1 /> */} + + + + + +
logo

@@ -15,11 +26,27 @@ function App() { target="_blank" rel="noopener noreferrer" > - Learn React + Aprendamos React

); } +function TodoCount(props){ + return( +

Ya completaste {props.completed} de {props.total} TODO's

+ ) +} + +function TodoItem(){ //componente + return( //elemento +
  • + V +

    Llorar con la llorona

    + X +
  • + ); +} + export default App; From 1499edaadf709fb3cfa12d00935bdf0a937cf79e Mon Sep 17 00:00:00 2001 From: Jairiana de Jesus Date: Thu, 14 Dec 2023 15:56:32 -0300 Subject: [PATCH 02/19] Componentes y elementos --- src/App.js | 59 ++++++++++++++++------------------------------- src/TodoButton.js | 7 ++++++ src/TodoCount.js | 7 ++++++ src/TodoItem.js | 11 +++++++++ src/TodoList.js | 9 ++++++++ src/TodoSearch.js | 7 ++++++ 6 files changed, 61 insertions(+), 39 deletions(-) create mode 100644 src/TodoButton.js create mode 100644 src/TodoCount.js create mode 100644 src/TodoItem.js create mode 100644 src/TodoList.js create mode 100644 src/TodoSearch.js diff --git a/src/App.js b/src/App.js index f3ac77f91..aa51a96bc 100644 --- a/src/App.js +++ b/src/App.js @@ -1,52 +1,33 @@ +// eslint-disable-next-line no-unused-vars import logo from './platzi.webp'; +import { TodoCount } from './TodoCount'; +import { TodoSearch } from './TodoSearch'; +import { TodoList } from './TodoList'; +import { TodoItem } from './TodoItem'; +import { TodoButton } from './TodoButton'; import './App.css'; function App() { return ( // a partir de aqui no estamos incorporando html, sino JSX
    - {/* ¿ Cómo llamo a un componente? Escribiendo su nombre con la siguiente sintáxis < Componente1 /> */} - - - - - + {/* ¿ Cómo llamo a un componente? Escribiendo su nombre con la siguiente sintáxis < Componente1 /> */} + + -
    - logo -

    - Edita el archivo src/App.js y guarda para recargar. -

    - - Aprendamos React - -
    + + + + + + + +
    ); } -function TodoCount(props){ - return( -

    Ya completaste {props.completed} de {props.total} TODO's

    - ) -} - -function TodoItem(){ //componente - return( //elemento -
  • - V -

    Llorar con la llorona

    - X -
  • - ); -} - export default App; diff --git a/src/TodoButton.js b/src/TodoButton.js new file mode 100644 index 000000000..d45a4d031 --- /dev/null +++ b/src/TodoButton.js @@ -0,0 +1,7 @@ +function TodoButton() { + return ( + + ) +} + +export {TodoButton} \ No newline at end of file diff --git a/src/TodoCount.js b/src/TodoCount.js new file mode 100644 index 000000000..69ccff408 --- /dev/null +++ b/src/TodoCount.js @@ -0,0 +1,7 @@ +function TodoCount(){ + return( +

    Ya completaste 3 de 5 TODO's

    + ) +} + +export {TodoCount} \ No newline at end of file diff --git a/src/TodoItem.js b/src/TodoItem.js new file mode 100644 index 000000000..726c3b3cb --- /dev/null +++ b/src/TodoItem.js @@ -0,0 +1,11 @@ +function TodoItem(){ //componente + return( //elemento +
  • + V +

    Llorar con la llorona

    + X +
  • + ); +} + +export {TodoItem} \ No newline at end of file diff --git a/src/TodoList.js b/src/TodoList.js new file mode 100644 index 000000000..759b3920a --- /dev/null +++ b/src/TodoList.js @@ -0,0 +1,9 @@ +function TodoList(props){ + return( + + ) +} + +export {TodoList} \ No newline at end of file diff --git a/src/TodoSearch.js b/src/TodoSearch.js new file mode 100644 index 000000000..4401af3aa --- /dev/null +++ b/src/TodoSearch.js @@ -0,0 +1,7 @@ +function TodoSearch(){ + return( + + ) +} + +export {TodoSearch} \ No newline at end of file From 397ae7a1ffb2d53c3a6172ad6ddfd8595d12efb6 Mon Sep 17 00:00:00 2001 From: Jairiana de Jesus Date: Thu, 14 Dec 2023 16:44:39 -0300 Subject: [PATCH 03/19] Props y atributos --- src/App.js | 26 ++++++++++++++++++-------- src/TodoCount.js | 4 ++-- src/TodoItem.js | 4 ++-- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/App.js b/src/App.js index aa51a96bc..301a42a8e 100644 --- a/src/App.js +++ b/src/App.js @@ -6,27 +6,37 @@ import { TodoList } from './TodoList'; import { TodoItem } from './TodoItem'; import { TodoButton } from './TodoButton'; import './App.css'; +import React from 'react'; + +const defaultTodos = [ + {text: 'cortar las hojas', completed: true}, + {text: 'cortar el papel tuales', completed: false}, + {text: 'cortarte las uñas', completed: true}, + {text: 'cortate el acbello', completed: false}, +] function App() { return ( // a partir de aqui no estamos incorporando html, sino JSX -
    + {/* ¿ Cómo llamo a un componente? Escribiendo su nombre con la siguiente sintáxis < Componente1 /> */} - - - - + {defaultTodos.map(todo =>( + + ))} -
    + ); } diff --git a/src/TodoCount.js b/src/TodoCount.js index 69ccff408..2e973596c 100644 --- a/src/TodoCount.js +++ b/src/TodoCount.js @@ -1,6 +1,6 @@ -function TodoCount(){ +function TodoCount({total, completed}){ return( -

    Ya completaste 3 de 5 TODO's

    +

    Ya completaste {completed} de {total} TODO's

    ) } diff --git a/src/TodoItem.js b/src/TodoItem.js index 726c3b3cb..eeb53f358 100644 --- a/src/TodoItem.js +++ b/src/TodoItem.js @@ -1,8 +1,8 @@ -function TodoItem(){ //componente +function TodoItem(props){ //componente return( //elemento
  • V -

    Llorar con la llorona

    +

    {props.text}

    X
  • ); From 0ffe23b433e3ab8780fb93f7a32e6184ea2a3d70 Mon Sep 17 00:00:00 2001 From: Jairiana de Jesus Date: Sat, 16 Dec 2023 16:52:17 -0300 Subject: [PATCH 04/19] Estilos CSS con react --- src/App.css | 38 ----------------------------------- src/App.js | 40 +++++++++++++++++++------------------ src/TodoButton.js | 2 ++ src/TodoCount.js | 7 ++++++- src/TodoItem.js | 10 +++++++--- src/TodoList.js | 3 +++ src/TodoSearch.js | 5 ++++- src/css/TodoButton.css | 16 +++++++++++++++ src/css/TodoCount.css | 8 ++++++++ src/css/TodoItem.css | 45 ++++++++++++++++++++++++++++++++++++++++++ src/css/TodoList.css | 5 +++++ src/css/TodoSearch.css | 15 ++++++++++++++ src/index.css | 7 ++++++- 13 files changed, 138 insertions(+), 63 deletions(-) delete mode 100644 src/App.css create mode 100644 src/css/TodoButton.css create mode 100644 src/css/TodoCount.css create mode 100644 src/css/TodoItem.css create mode 100644 src/css/TodoList.css create mode 100644 src/css/TodoSearch.css diff --git a/src/App.css b/src/App.css deleted file mode 100644 index 4661df052..000000000 --- a/src/App.css +++ /dev/null @@ -1,38 +0,0 @@ -.App { - text-align: center; -} - -.App-logo { - height: 40vmin; - pointer-events: none; -} - -@media (prefers-reduced-motion: no-preference) { - .App-logo { - animation: App-logo-spin infinite 20s linear; - } -} - -.App-header { - background-color: #233553; - min-height: 100vh; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - font-size: calc(10px + 2vmin); - color: white; -} - -.App-link { - color: #97ca3f; -} - -@keyframes App-logo-spin { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } -} diff --git a/src/App.js b/src/App.js index 301a42a8e..9adeb7804 100644 --- a/src/App.js +++ b/src/App.js @@ -5,38 +5,40 @@ import { TodoSearch } from './TodoSearch'; import { TodoList } from './TodoList'; import { TodoItem } from './TodoItem'; import { TodoButton } from './TodoButton'; -import './App.css'; import React from 'react'; const defaultTodos = [ - {text: 'cortar las hojas', completed: true}, + {text: 'lorem ipsut, lorem ipsut, lorem ipsut, lorem ipsut, lorem ipsut, lorem ipsut, lorem ipsut, lorem ipsut, lorem ipsut', completed: true}, {text: 'cortar el papel tuales', completed: false}, {text: 'cortarte las uñas', completed: true}, {text: 'cortate el acbello', completed: false}, + { text: 'Cortar cebolla', completed: true }, + { text: 'Tomar el Curso de Intro a React.js', completed: false }, + { text: 'Llorar con la Llorona', completed: false }, + { text: 'LALALALALA', completed: false }, + {text: 'cortarte las uñas', completed: true}, ] function App() { return ( // a partir de aqui no estamos incorporando html, sino JSX - + <> {/*→este "codigo" sin declaracion alguna es igual o hace la misma funcion que React.Fragment*/} {/* ¿ Cómo llamo a un componente? Escribiendo su nombre con la siguiente sintáxis < Componente1 /> */} - - + + - - {defaultTodos.map(todo =>( - - ))} - - - - - + + {defaultTodos.map(todo =>( + + ))} + + + + ); } diff --git a/src/TodoButton.js b/src/TodoButton.js index d45a4d031..22ee2edf6 100644 --- a/src/TodoButton.js +++ b/src/TodoButton.js @@ -1,3 +1,5 @@ +import './css/TodoButton.css'; + function TodoButton() { return ( diff --git a/src/TodoCount.js b/src/TodoCount.js index 2e973596c..f1962463e 100644 --- a/src/TodoCount.js +++ b/src/TodoCount.js @@ -1,6 +1,11 @@ +import './css/TodoCount.css'; + + function TodoCount({total, completed}){ return( -

    Ya completaste {completed} de {total} TODO's

    +

    Ya completaste {completed} de {total} TODO's

    ) } diff --git a/src/TodoItem.js b/src/TodoItem.js index eeb53f358..841f8cf4f 100644 --- a/src/TodoItem.js +++ b/src/TodoItem.js @@ -1,9 +1,13 @@ +/* eslint-disable jsx-a11y/anchor-is-valid */ +import './css/TodoItem.css'; + + function TodoItem(props){ //componente return( //elemento
  • - V -

    {props.text}

    - X + * +

    {props.text}

    + X
  • ); } diff --git a/src/TodoList.js b/src/TodoList.js index 759b3920a..9162678ee 100644 --- a/src/TodoList.js +++ b/src/TodoList.js @@ -1,3 +1,6 @@ +import './css/TodoList.css'; + + function TodoList(props){ return(
      diff --git a/src/TodoSearch.js b/src/TodoSearch.js index 4401af3aa..e968416f0 100644 --- a/src/TodoSearch.js +++ b/src/TodoSearch.js @@ -1,6 +1,9 @@ +import './css/TodoSearch.css'; + + function TodoSearch(){ return( - + ) } diff --git a/src/css/TodoButton.css b/src/css/TodoButton.css new file mode 100644 index 000000000..a62f3c502 --- /dev/null +++ b/src/css/TodoButton.css @@ -0,0 +1,16 @@ +button{ + position: fixed; + bottom: 20px; + height: auto; + right: 20px; + background-color: #fff0ac; + border: none; + border-radius: 50%; + font-size: 70px; + padding: 5px 30px; + margin: 30px; + font-family: ui-monospace; + font-weight: bold; + color: #1b191cb5; + box-shadow: 0 0 20px #d8ad7c; +} \ No newline at end of file diff --git a/src/css/TodoCount.css b/src/css/TodoCount.css new file mode 100644 index 000000000..58a3fa79b --- /dev/null +++ b/src/css/TodoCount.css @@ -0,0 +1,8 @@ +h1 { + text-align: center; + font-family: emoji; + font-size: 50px; + text-shadow: 0 0 5px #d8ad7c; + color: wheat; + margin: 50px; +} \ No newline at end of file diff --git a/src/css/TodoItem.css b/src/css/TodoItem.css new file mode 100644 index 000000000..2f81300a8 --- /dev/null +++ b/src/css/TodoItem.css @@ -0,0 +1,45 @@ +li{ + display: flex; + align-items: center; + height: auto; + width: 90%; + margin: 0 auto; + margin-bottom: 15px; + border-radius: 10px; + background-color: #3b3434; + justify-content: space-evenly; +} + + +.icon{cursor:pointer; + display:flex; + justify-content:center; + align-items:center; + height:48px; + width:48px; + font-size:xx-large;color: #afa4ab; + font-weight:700} +.icon-check--active{color:#9262f78c} + +.parrafo{ + width: 85%; + font-family: monospace; + color: #f3e1f7; + font-size: 22px; +} .list-parrafo--tachado{ + text-decoration: line-through; +} + +.icon-delete{ + font-size: x-large; + color: #ffffff8a; + font-family: ui-monospace; + font-weight: 700; + border-radius: 50px; + padding: 3px 6px; + position: relative; +} +.icon-delete:hover { + color: #ff4747; + text-shadow: 0 0 10px red; +} \ No newline at end of file diff --git a/src/css/TodoList.css b/src/css/TodoList.css new file mode 100644 index 000000000..328c2c6f5 --- /dev/null +++ b/src/css/TodoList.css @@ -0,0 +1,5 @@ +ul { + padding: 0 10px; + margin: 30px 5px; + list-style: none; +} \ No newline at end of file diff --git a/src/css/TodoSearch.css b/src/css/TodoSearch.css new file mode 100644 index 000000000..3b6298554 --- /dev/null +++ b/src/css/TodoSearch.css @@ -0,0 +1,15 @@ +.Buscar { + width: 50%; + height: 50px; + display: block; + font-size: x-large; + padding: 2px 20px; + margin: 5px auto; + color: darkgrey; + border-style: none; + background-color: #544e42; + box-shadow: 0 4px 5px #6b6456c2; + border-radius: 10px; + border-bottom-style: groove; + font-family: ui-monospace; +} \ No newline at end of file diff --git a/src/index.css b/src/index.css index ec2585e8c..f6819b332 100644 --- a/src/index.css +++ b/src/index.css @@ -5,8 +5,13 @@ body { sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; + background: #f3e1f7; + height: 100%; + background-image: url(https://i.pinimg.com/736x/0b/e7/c3/0be7c304a8d2eb4f3eb51f1fe31c345e.jpg); + background-repeat: no-repeat; + background-size: cover; + background-attachment: fixed; } - code { font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace; From 1d3c3c8b51d4c2974ed0e0682e82694d37ad963a Mon Sep 17 00:00:00 2001 From: Jairiana de Jesus Date: Mon, 18 Dec 2023 11:56:26 -0300 Subject: [PATCH 05/19] onClick y onChange --- src/TodoButton.js | 6 +++++- src/TodoSearch.js | 12 ++++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/TodoButton.js b/src/TodoButton.js index 22ee2edf6..14d3aa865 100644 --- a/src/TodoButton.js +++ b/src/TodoButton.js @@ -2,7 +2,11 @@ import './css/TodoButton.css'; function TodoButton() { return ( - + ) } diff --git a/src/TodoSearch.js b/src/TodoSearch.js index e968416f0..bedaec7bb 100644 --- a/src/TodoSearch.js +++ b/src/TodoSearch.js @@ -1,9 +1,17 @@ import './css/TodoSearch.css'; - function TodoSearch(){ return( - + { + console.log('escribiste algo en el search ') + console.log(event) + console.log(event.target) + console.log(event.target.value) + } + }/> ) } From 95ca5f84c44bf9e36013b43e1f8e534765df37e1 Mon Sep 17 00:00:00 2001 From: Jairiana de Jesus Date: Mon, 18 Dec 2023 19:37:07 -0300 Subject: [PATCH 06/19] Estado --- src/TodoSearch.js | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/TodoSearch.js b/src/TodoSearch.js index bedaec7bb..f1b3184b4 100644 --- a/src/TodoSearch.js +++ b/src/TodoSearch.js @@ -1,17 +1,24 @@ import './css/TodoSearch.css'; +import React from 'react' function TodoSearch(){ + const [searchValue, setSearchValue] = React.useState(''); + console.log('Los usuarios buscan todos de ' + searchValue)//concatenacion de un console.log, se mostaa el codigo ejecutado gacias a la linea 19 return( { - console.log('escribiste algo en el search ') - console.log(event) - console.log(event.target) - console.log(event.target.value) - } - }/> + // onChange = {(event) => { + // console.log('escribiste algo en el search ') //mensjae que aparece cuadno escriba algo + // console.log(event) // mensaje que aparece y dice que tipo de evento es + // console.log(event.target) // mensja que aparece el tipo de evnto mas detallado + // console.log(event.target.value) // mensaje que aparece el valor del search lo cual dependa del usuario + // } 8jj + value = {searchValue} + onChange={(event) => { + setSearchValue(event.target.value) //valor del usuario al ñlo que escruba en el search + }} + /> ) } From 72c1cbe934f1772b7a3ff929a558003be6b7db24 Mon Sep 17 00:00:00 2001 From: Jairiana de Jesus Date: Wed, 20 Dec 2023 12:54:18 -0300 Subject: [PATCH 07/19] Contando TODOs --- src/App.js | 19 ++++++++++++++++--- src/TodoSearch.js | 8 +++++--- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/App.js b/src/App.js index 9adeb7804..71acda02d 100644 --- a/src/App.js +++ b/src/App.js @@ -20,12 +20,25 @@ const defaultTodos = [ ] function App() { - return ( // a partir de aqui no estamos incorporando html, sino JSX + const [todos, setTodos] = React.useState(defaultTodos) //nuevo estado + + const completedTodos = todos.filter(todo => !!todo.completed).length; + //Para filtrar un elemento de un array (manipulacion de arrays) existen dos formas: find y filter. Find te permite filtrar un elemento, UN solo eelemento lo cual va a ser el primero de una lista, en cambio del filter; te filtrara TODOS los elemntos de una lista + //segundo; se hace una arrowFutsion; '(todo => todo.completed)' se llama -todo- a aquellos todos que tengan el estado -completed- como true. Pero a simple vista se ve que va a llamar es a un valor, y nosotros necesitamos un buleano, por lo tanto se escribe con doble explamacion, para que esos valores se transformen en boleano '(todo => !!todo.completed)' + //tercero; se pone la propiedad 'lwngth' para recibir las cantidades del array que se quiere filtrar + const totalTodos = todos.length; //contador de todos en total + const [searchValue, setSearchValue] = React.useState(''); + console.log('Los usuarios buscan todos de ' + searchValue) //concatenacion de un console.log, se mostaa el codigo ejecutado gacias a la linea 20 del componente TodoSearch + + return ( // a partir de aqui no estamos incorporando html, sino JSX <> {/*→este "codigo" sin declaracion alguna es igual o hace la misma funcion que React.Fragment*/} {/* ¿ Cómo llamo a un componente? Escribiendo su nombre con la siguiente sintáxis < Componente1 /> */} - - + + {defaultTodos.map(todo =>( diff --git a/src/TodoSearch.js b/src/TodoSearch.js index f1b3184b4..54a19d751 100644 --- a/src/TodoSearch.js +++ b/src/TodoSearch.js @@ -1,9 +1,11 @@ import './css/TodoSearch.css'; import React from 'react' -function TodoSearch(){ - const [searchValue, setSearchValue] = React.useState(''); - console.log('Los usuarios buscan todos de ' + searchValue)//concatenacion de un console.log, se mostaa el codigo ejecutado gacias a la linea 19 +function TodoSearch({ + searchValue, + setSearchValue +}){ + //seelimina el codigo del estado searchValue para colocarlo en el componente App, pero para que esto siga teniendon su funcion; se llaman los estados como parametros en esta funcion return( Date: Tue, 26 Dec 2023 11:59:18 -0300 Subject: [PATCH 08/19] Buscando TODOs --- src/App.js | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/src/App.js b/src/App.js index 71acda02d..596c068b0 100644 --- a/src/App.js +++ b/src/App.js @@ -8,10 +8,9 @@ import { TodoButton } from './TodoButton'; import React from 'react'; const defaultTodos = [ - {text: 'lorem ipsut, lorem ipsut, lorem ipsut, lorem ipsut, lorem ipsut, lorem ipsut, lorem ipsut, lorem ipsut, lorem ipsut', completed: true}, - {text: 'cortar el papel tuales', completed: false}, - {text: 'cortarte las uñas', completed: true}, - {text: 'cortate el acbello', completed: false}, + { text: 'Cortar cebolla', completed: true }, + { text: 'Tomar el Curso de Intro a React.js', completed: false }, + { text: 'Usar estados derivados', completed: true }, { text: 'Cortar cebolla', completed: true }, { text: 'Tomar el Curso de Intro a React.js', completed: false }, { text: 'Llorar con la Llorona', completed: false }, @@ -20,28 +19,43 @@ const defaultTodos = [ ] function App() { - const [todos, setTodos] = React.useState(defaultTodos) //nuevo estado + const [todos, setTodos] = React.useState(defaultTodos); //nuevo estado + + const [searchValue, setSearchValue] = React.useState(''); + console.log('Los usuarios buscan todos de ' + searchValue) //concatenacion de un console.log, se mostaa el codigo ejecutado gacias a la linea 20 del componente TodoSearch const completedTodos = todos.filter(todo => !!todo.completed).length; //Para filtrar un elemento de un array (manipulacion de arrays) existen dos formas: find y filter. Find te permite filtrar un elemento, UN solo eelemento lo cual va a ser el primero de una lista, en cambio del filter; te filtrara TODOS los elemntos de una lista //segundo; se hace una arrowFutsion; '(todo => todo.completed)' se llama -todo- a aquellos todos que tengan el estado -completed- como true. Pero a simple vista se ve que va a llamar es a un valor, y nosotros necesitamos un buleano, por lo tanto se escribe con doble explamacion, para que esos valores se transformen en boleano '(todo => !!todo.completed)' //tercero; se pone la propiedad 'lwngth' para recibir las cantidades del array que se quiere filtrar const totalTodos = todos.length; //contador de todos en total + + + const searchedTodos = todos.filter( //estado derivado de buscar todos + (todo) => { //arrow futsion + //return todo.text.toLowerCase().includes(searchValue.toLowerCase()) + //aqui estamos preguntando si por cada 'todo'; si el texto (text) de ese todo incluye (includes) en alñguna parte ese texto que forma parte del searchValue + //el codigo '.toLowerCase()' convuerte toda aquellas minusculas a mayusculas y viceversa, o mejor dicho hace mas facil la busqueda de todos + //esta es una linea de codigo larga o mejor dicho de JavaScript moderno, para ordenarnos mas nos guiamos con la de abajo ↓ + + const todoText = todo.text.toLowerCase(); + const searchText = searchValue.toLowerCase(); + return todoText.includes(searchText); + } + ); - const [searchValue, setSearchValue] = React.useState(''); - console.log('Los usuarios buscan todos de ' + searchValue) //concatenacion de un console.log, se mostaa el codigo ejecutado gacias a la linea 20 del componente TodoSearch return ( // a partir de aqui no estamos incorporando html, sino JSX - <> {/*→este "codigo" sin declaracion alguna es igual o hace la misma funcion que React.Fragment*/} + <> {/* → este "codigo" sin declaracion alguna es igual o hace la misma funcion que React.Fragment*/} {/* ¿ Cómo llamo a un componente? Escribiendo su nombre con la siguiente sintáxis < Componente1 /> */} - {defaultTodos.map(todo =>( + {searchedTodos.map(todo =>( Date: Tue, 26 Dec 2023 17:18:29 -0300 Subject: [PATCH 09/19] completando TODOs (true) --- src/App.js | 17 +++++++++-- src/TodoItem.js | 12 ++++++-- src/TodoSearch.js | 2 +- src/css/TodoItem.css | 70 ++++++++++++++++++++++---------------------- 4 files changed, 60 insertions(+), 41 deletions(-) diff --git a/src/App.js b/src/App.js index 596c068b0..8d1cc0288 100644 --- a/src/App.js +++ b/src/App.js @@ -1,3 +1,4 @@ +/* eslint-disable eqeqeq */ // eslint-disable-next-line no-unused-vars import logo from './platzi.webp'; import { TodoCount } from './TodoCount'; @@ -11,8 +12,8 @@ const defaultTodos = [ { text: 'Cortar cebolla', completed: true }, { text: 'Tomar el Curso de Intro a React.js', completed: false }, { text: 'Usar estados derivados', completed: true }, - { text: 'Cortar cebolla', completed: true }, - { text: 'Tomar el Curso de Intro a React.js', completed: false }, + { text: 'Cortar berenjena', completed: true }, + { text: 'Tomar la ruta de JavaScript a pronfundidad', completed: false }, { text: 'Llorar con la Llorona', completed: false }, { text: 'LALALALALA', completed: false }, {text: 'cortarte las uñas', completed: true}, @@ -44,6 +45,17 @@ function App() { } ); + const completeTodo = (text) => { // text que representa el texto de la tarea que se va a completar. + console.log('click') //Esta línea imprime 'click' en la consola cada vez que se llama a la función completeTodo. Esto podría ser útil para depurar o entender cuándo se activa esta función. + + const newTodos = [...todos]; //Crea una copia de la matriz todos utilizando el operador de propagación (...). Esto es importante para no mutar directamente la matriz original. + const todoIndex = newTodos.findIndex( + (todo) => todo.text === text + );//Encuentra el índice en el arreglo newTodos donde el texto de la tarea coincide con el argumento text proporcionado. + + newTodos[todoIndex].completed = true; //Cambia la propiedad completed de la tarea encontrada en el paso anterior a true, lo que indica que la tarea ha sido completada. + setTodos(newTodos); //Actualiza el estado de todos con la nueva matriz de tareas donde la tarea indicada se marca como completada. + } return ( // a partir de aqui no estamos incorporando html, sino JSX <> {/* → este "codigo" sin declaracion alguna es igual o hace la misma funcion que React.Fragment*/} @@ -60,6 +72,7 @@ function App() { key={todo.text} text={todo.text} completed={todo.completed} + onComplete={() => completeTodo(todo.text)} //evento del onClick del archivo TodoItem /> ))} diff --git a/src/TodoItem.js b/src/TodoItem.js index 841f8cf4f..3bc233d20 100644 --- a/src/TodoItem.js +++ b/src/TodoItem.js @@ -4,9 +4,15 @@ import './css/TodoItem.css'; function TodoItem(props){ //componente return( //elemento -
    • - * -

      {props.text}

      +
    • + + * + +

      + {props.text} +

      X
    • ); diff --git a/src/TodoSearch.js b/src/TodoSearch.js index 54a19d751..101416a9b 100644 --- a/src/TodoSearch.js +++ b/src/TodoSearch.js @@ -9,7 +9,7 @@ function TodoSearch({ return( { // console.log('escribiste algo en el search ') //mensjae que aparece cuadno escriba algo // console.log(event) // mensaje que aparece y dice que tipo de evento es diff --git a/src/css/TodoItem.css b/src/css/TodoItem.css index 2f81300a8..315aad14d 100644 --- a/src/css/TodoItem.css +++ b/src/css/TodoItem.css @@ -1,45 +1,45 @@ -li{ - display: flex; - align-items: center; - height: auto; - width: 90%; - margin: 0 auto; - margin-bottom: 15px; - border-radius: 10px; - background-color: #3b3434; - justify-content: space-evenly; +.TodoItem{ + background-color:#fafafa; + position:relative; + display:flex; + justify-content:center; + align-items:center; + margin-top:24px; + box-shadow:0 5px 50px rgba(32,35,41,.15) +} + +.TodoItem-p{ + margin:24px 0 24px 24px; + width:calc(100% - 120px); + font-size:18px; + line-height:24px; + font-weight:400 } +.TodoItem-p--complete{ + text-decoration:line-through +} -.icon{cursor:pointer; +.Icon{ + cursor:pointer; display:flex; justify-content:center; align-items:center; height:48px; width:48px; - font-size:xx-large;color: #afa4ab; - font-weight:700} -.icon-check--active{color:#9262f78c} - -.parrafo{ - width: 85%; - font-family: monospace; - color: #f3e1f7; - font-size: 22px; -} .list-parrafo--tachado{ - text-decoration: line-through; + font-size:24px; + font-weight:700 } - -.icon-delete{ - font-size: x-large; - color: #ffffff8a; - font-family: ui-monospace; - font-weight: 700; - border-radius: 50px; - padding: 3px 6px; - position: relative; +.Icon-check{ + position:absolute; + left:12px +} +.Icon-check--active{ + color:#4caf50 +} +.Icon-delete{ + position:absolute; + top:-24px; + right:0 } -.icon-delete:hover { - color: #ff4747; - text-shadow: 0 0 10px red; -} \ No newline at end of file +.Icon-delete:hover{color:red} \ No newline at end of file From 0fc8ae71997fbfc3e601d1fcafcf47d1ce9cc44b Mon Sep 17 00:00:00 2001 From: Jairiana de Jesus Date: Tue, 26 Dec 2023 18:04:23 -0300 Subject: [PATCH 10/19] eliminando TODOs (delete) --- src/App.js | 22 +++++++++++++++++----- src/TodoItem.js | 4 +++- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/App.js b/src/App.js index 8d1cc0288..d73d05129 100644 --- a/src/App.js +++ b/src/App.js @@ -9,21 +9,20 @@ import { TodoButton } from './TodoButton'; import React from 'react'; const defaultTodos = [ - { text: 'Cortar cebolla', completed: true }, + { text: 'Cortar cebolla', completed: false }, { text: 'Tomar el Curso de Intro a React.js', completed: false }, - { text: 'Usar estados derivados', completed: true }, - { text: 'Cortar berenjena', completed: true }, + { text: 'Usar estados derivados', completed: false }, + { text: 'Cortar berenjena', completed: false }, { text: 'Tomar la ruta de JavaScript a pronfundidad', completed: false }, { text: 'Llorar con la Llorona', completed: false }, { text: 'LALALALALA', completed: false }, - {text: 'cortarte las uñas', completed: true}, + {text: 'cortarte las uñas', completed: false}, ] function App() { const [todos, setTodos] = React.useState(defaultTodos); //nuevo estado const [searchValue, setSearchValue] = React.useState(''); - console.log('Los usuarios buscan todos de ' + searchValue) //concatenacion de un console.log, se mostaa el codigo ejecutado gacias a la linea 20 del componente TodoSearch const completedTodos = todos.filter(todo => !!todo.completed).length; //Para filtrar un elemento de un array (manipulacion de arrays) existen dos formas: find y filter. Find te permite filtrar un elemento, UN solo eelemento lo cual va a ser el primero de una lista, en cambio del filter; te filtrara TODOS los elemntos de una lista @@ -57,6 +56,18 @@ function App() { setTodos(newTodos); //Actualiza el estado de todos con la nueva matriz de tareas donde la tarea indicada se marca como completada. } + const deleteTodo = (text) => { + console.log('click delete') + + const newTodos = [...todos]; + const todoIndex = newTodos.findIndex( + (todo) => todo.text === text + ); + + newTodos.splice(todoIndex, 1); //Utiliza splice para eliminar un elemento en el índice todoIndex de la matriz newTodos. En este caso, se elimina un solo elemento a partir de ese índice. + setTodos(newTodos); + } + return ( // a partir de aqui no estamos incorporando html, sino JSX <> {/* → este "codigo" sin declaracion alguna es igual o hace la misma funcion que React.Fragment*/} {/* ¿ Cómo llamo a un componente? Escribiendo su nombre con la siguiente sintáxis < Componente1 /> */} @@ -73,6 +84,7 @@ function App() { text={todo.text} completed={todo.completed} onComplete={() => completeTodo(todo.text)} //evento del onClick del archivo TodoItem + onDelete={() => deleteTodo(todo.text)} //evento del onClick del archivo TodoItem /> ))}
      diff --git a/src/TodoItem.js b/src/TodoItem.js index 3bc233d20..4ba5efc5a 100644 --- a/src/TodoItem.js +++ b/src/TodoItem.js @@ -13,7 +13,9 @@ function TodoItem(props){ //componente

      {props.text}

      - X + X ); } From 3c42c51f9aeacd7368831124bb819345e1245594 Mon Sep 17 00:00:00 2001 From: Jairiana de Jesus Date: Thu, 28 Dec 2023 11:50:29 -0300 Subject: [PATCH 11/19] Iconos en React: librerias y SVG --- src/App.js | 1 - src/CompleteIcon.js | 13 +++++++++++++ src/DeleteIcon.js | 13 +++++++++++++ src/TodoIcon.js | 19 +++++++++++++++++++ src/TodoItem.js | 16 +++++++--------- src/svg/check.svg | 3 +++ src/svg/delete.svg | 3 +++ 7 files changed, 58 insertions(+), 10 deletions(-) create mode 100644 src/CompleteIcon.js create mode 100644 src/DeleteIcon.js create mode 100644 src/TodoIcon.js create mode 100644 src/svg/check.svg create mode 100644 src/svg/delete.svg diff --git a/src/App.js b/src/App.js index d73d05129..7b1230e6f 100644 --- a/src/App.js +++ b/src/App.js @@ -1,6 +1,5 @@ /* eslint-disable eqeqeq */ // eslint-disable-next-line no-unused-vars -import logo from './platzi.webp'; import { TodoCount } from './TodoCount'; import { TodoSearch } from './TodoSearch'; import { TodoList } from './TodoList'; diff --git a/src/CompleteIcon.js b/src/CompleteIcon.js new file mode 100644 index 000000000..ecb0057f6 --- /dev/null +++ b/src/CompleteIcon.js @@ -0,0 +1,13 @@ +import React from 'react'; +import { TodoIcon } from './TodoIcon' //Importa React y el componente TodoIcon desde un archivo llamado TodoIcon.js. + +function CompleteIcon() { + return ( + // se encarga de mostrar un ícono de verificación (check) para representar la acción de completar una tarea. Además, intenta pasar una propiedad de color 'green', aunque en el código del componente TodoIcon no se está utilizando explícitamente la propiedad de color. + ) +} + +export { CompleteIcon } //Exporta el componente CompleteIcon para su uso en otras partes de la aplicación. \ No newline at end of file diff --git a/src/DeleteIcon.js b/src/DeleteIcon.js new file mode 100644 index 000000000..f0e7f7214 --- /dev/null +++ b/src/DeleteIcon.js @@ -0,0 +1,13 @@ +import React from 'react'; +import { TodoIcon } from './TodoIcon' //Se importa React y el componente TodoIcon desde un archivo llamado TodoIcon.js. + +function DeleteIcon() { //Define el componente DeleteIcon. Este componente renderiza el componente TodoIcon con las propiedades type='delete' y color='red' + return ( + + ) // DeleteIcon se encarga de mostrar un ícono de eliminación para representar la acción de borrar o eliminar una tarea de la lista. Además, intenta pasar una propiedad de color 'red', aunque en el código del componente TodoIcon no se está utilizando explícitamente la propiedad de color. +} + +export { DeleteIcon } //Exporta el componente DeleteIcon para su uso en otras partes de la aplicación. \ No newline at end of file diff --git a/src/TodoIcon.js b/src/TodoIcon.js new file mode 100644 index 000000000..697723bd7 --- /dev/null +++ b/src/TodoIcon.js @@ -0,0 +1,19 @@ +import {ReactComponent as CheckSVG} from './svg/check.svg'; +import {ReactComponent as DeleteSVG} from './svg/delete.svg'; + //Aquí se importan dos imágenes SVG usando la sintaxis de ReactComponent. Estas imágenes se usan como íconos para la lista de tareas. + +const iconType = { + 'check' : , + 'delete' : +} //Se crea un objeto iconType que asocia cadenas ('check' y 'delete') con los componentes y respectivamente. Esto permite seleccionar dinámicamente el ícono deseado más adelante en base al tipo. + +function TodoIcon({type}){//Se define el componente TodoIcon que recibe una propiedad type. Este componente renderiza un ícono () con una clase CSS basada en el tipo de ícono que recibe. + return ( + + {iconType[type]} + //Dentro del , se usa iconType[type] para mostrar el componente SVG correspondiente según el tipo proporcionado. + ) +} + + +export{ TodoIcon } //Se exporta el componente TodoIcon para que pueda ser utilizado en otras partes de la aplicación. \ No newline at end of file diff --git a/src/TodoItem.js b/src/TodoItem.js index 4ba5efc5a..e26970354 100644 --- a/src/TodoItem.js +++ b/src/TodoItem.js @@ -1,21 +1,19 @@ /* eslint-disable jsx-a11y/anchor-is-valid */ import './css/TodoItem.css'; - +import {CompleteIcon} from './CompleteIcon'; +import {DeleteIcon} from './DeleteIcon'; + //Se están importando dos componentes: CompleteIcon desde el archivo './CompleteIcon' y DeleteIcon desde el archivo './DeleteIcon'. function TodoItem(props){ //componente return( //elemento
    • - - * - + +

      {props.text}

      - X + +
    • ); } diff --git a/src/svg/check.svg b/src/svg/check.svg new file mode 100644 index 000000000..1d50a077f --- /dev/null +++ b/src/svg/check.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/svg/delete.svg b/src/svg/delete.svg new file mode 100644 index 000000000..8783343bb --- /dev/null +++ b/src/svg/delete.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file From ea3766ca3a7207c1ddb5f038ae33d2ed8722d88d Mon Sep 17 00:00:00 2001 From: Jairiana de Jesus Date: Thu, 28 Dec 2023 18:16:43 -0300 Subject: [PATCH 12/19] iconos con colores dinamicos --- src/App.js | 2 +- src/CompleteIcon.js | 7 ++++--- src/DeleteIcon.js | 5 +++-- src/TodoIcon.js | 36 ++++++++++++++++++++++++++++-------- src/TodoItem.js | 9 ++++++--- src/css/TodoIcon.css | 40 ++++++++++++++++++++++++++++++++++++++++ src/css/TodoItem.css | 24 ------------------------ 7 files changed, 82 insertions(+), 41 deletions(-) create mode 100644 src/css/TodoIcon.css diff --git a/src/App.js b/src/App.js index 7b1230e6f..8acf3d16c 100644 --- a/src/App.js +++ b/src/App.js @@ -9,7 +9,7 @@ import React from 'react'; const defaultTodos = [ { text: 'Cortar cebolla', completed: false }, - { text: 'Tomar el Curso de Intro a React.js', completed: false }, + { text: 'Tomar el Curso de Intro a React.js', completed: true }, { text: 'Usar estados derivados', completed: false }, { text: 'Cortar berenjena', completed: false }, { text: 'Tomar la ruta de JavaScript a pronfundidad', completed: false }, diff --git a/src/CompleteIcon.js b/src/CompleteIcon.js index ecb0057f6..6ccd8f467 100644 --- a/src/CompleteIcon.js +++ b/src/CompleteIcon.js @@ -1,12 +1,13 @@ import React from 'react'; import { TodoIcon } from './TodoIcon' //Importa React y el componente TodoIcon desde un archivo llamado TodoIcon.js. -function CompleteIcon() { +function CompleteIcon({completed, onComplete}) { return ( // se encarga de mostrar un ícono de verificación (check) para representar la acción de completar una tarea. Además, intenta pasar una propiedad de color 'green', aunque en el código del componente TodoIcon no se está utilizando explícitamente la propiedad de color. + color={completed ? 'green' : 'gray'} //si la propiedad completed es true, entonces se pone de colo verde... si no, se pone de color gris + onClick={onComplete} // funcion del click + /> // se encarga de mostrar un ícono de verificación (check) para representar la acción de completar una tarea. ) } diff --git a/src/DeleteIcon.js b/src/DeleteIcon.js index f0e7f7214..39b2be3f2 100644 --- a/src/DeleteIcon.js +++ b/src/DeleteIcon.js @@ -1,11 +1,12 @@ import React from 'react'; import { TodoIcon } from './TodoIcon' //Se importa React y el componente TodoIcon desde un archivo llamado TodoIcon.js. -function DeleteIcon() { //Define el componente DeleteIcon. Este componente renderiza el componente TodoIcon con las propiedades type='delete' y color='red' +function DeleteIcon({onDelete}) { //Define el componente DeleteIcon. Este componente renderiza el componente TodoIcon con las propiedades type='delete' y color='red' return ( ) // DeleteIcon se encarga de mostrar un ícono de eliminación para representar la acción de borrar o eliminar una tarea de la lista. Además, intenta pasar una propiedad de color 'red', aunque en el código del componente TodoIcon no se está utilizando explícitamente la propiedad de color. } diff --git a/src/TodoIcon.js b/src/TodoIcon.js index 697723bd7..a3be9a2ac 100644 --- a/src/TodoIcon.js +++ b/src/TodoIcon.js @@ -1,17 +1,37 @@ import {ReactComponent as CheckSVG} from './svg/check.svg'; import {ReactComponent as DeleteSVG} from './svg/delete.svg'; - //Aquí se importan dos imágenes SVG usando la sintaxis de ReactComponent. Estas imágenes se usan como íconos para la lista de tareas. + // → Aquí se importan dos imágenes SVG usando la sintaxis de ReactComponent. Estas imágenes se usan como íconos para la lista de tareas. +import './css/TodoIcon.css' const iconType = { - 'check' : , - 'delete' : -} //Se crea un objeto iconType que asocia cadenas ('check' y 'delete') con los componentes y respectivamente. Esto permite seleccionar dinámicamente el ícono deseado más adelante en base al tipo. -function TodoIcon({type}){//Se define el componente TodoIcon que recibe una propiedad type. Este componente renderiza un ícono () con una clase CSS basada en el tipo de ícono que recibe. + "check": (color) => ( + + ), + + "delete": (color) => ( + + ), + +}; + + +function TodoIcon({type, color, onClick}){ + //Se define el componente TodoIcon que recibe una propiedad type. Este componente renderiza un ícono () con una clase CSS basada en el tipo de ícono que recibe. return ( - - {iconType[type]} - //Dentro del , se usa iconType[type] para mostrar el componente SVG correspondiente según el tipo proporcionado. + + {/* → codigo para que los click de los icons funcionen */} + {iconType[type](color)} + //se llama al color como parametro -- Dentro del , se usa iconType[type] para mostrar el componente SVG correspondiente según el tipo proporcionado. ) } diff --git a/src/TodoItem.js b/src/TodoItem.js index e26970354..4a9bdce7e 100644 --- a/src/TodoItem.js +++ b/src/TodoItem.js @@ -7,13 +7,16 @@ import {DeleteIcon} from './DeleteIcon'; function TodoItem(props){ //componente return( //elemento
    • - +

      {props.text}

      - - + +
    • ); } diff --git a/src/css/TodoIcon.css b/src/css/TodoIcon.css new file mode 100644 index 000000000..94cd9b7c5 --- /dev/null +++ b/src/css/TodoIcon.css @@ -0,0 +1,40 @@ +/*estilos css SOLAMENTE paar los icons*/ +.Icon-container{ + cursor:pointer; + display:flex; + justify-content:center; + align-items:center; + height:48px; + width:48px; + font-size:24px; + font-weight:700 +} + +.Icon-container-check{ + position:absolute; + left:12px +}.Icon-container-check--active{ + color:#4caf50 +} + +.Icon-container-delete{ + position:absolute; + top:-24px; + right:0 +}.Icon-container-delete:hover{color:red} + + +.Icon-svg{ + width: 20px; + height: 20px; +} + +/*pdemos camviarle el color de los icons creados o aplicados en react, desde css +para que se vean como si estuvieramos usando un propiedad "color" pero en realidad se lo estamos modificando. +En este caso le estamos cambiando el color de los icons cuando el cursor este por encima de ellos*/ +.Icon-container-check:hover .Icon-svg { + fill:green; +} +.Icon-container-delete:hover .Icon-svg { + fill:red; +} diff --git a/src/css/TodoItem.css b/src/css/TodoItem.css index 315aad14d..98b84cad2 100644 --- a/src/css/TodoItem.css +++ b/src/css/TodoItem.css @@ -19,27 +19,3 @@ .TodoItem-p--complete{ text-decoration:line-through } - -.Icon{ - cursor:pointer; - display:flex; - justify-content:center; - align-items:center; - height:48px; - width:48px; - font-size:24px; - font-weight:700 -} -.Icon-check{ - position:absolute; - left:12px -} -.Icon-check--active{ - color:#4caf50 -} -.Icon-delete{ - position:absolute; - top:-24px; - right:0 -} -.Icon-delete:hover{color:red} \ No newline at end of file From e7fc57fb4707dff7dcf8b1c2238d98a0b1dca9d9 Mon Sep 17 00:00:00 2001 From: Jairiana de Jesus Date: Fri, 29 Dec 2023 17:37:58 -0300 Subject: [PATCH 13/19] Local Storage con Ract.js --- src/App.js | 83 ++++++++++++++++++++++-------------- src/archive/Local Storage.md | 49 +++++++++++++++++++++ 2 files changed, 101 insertions(+), 31 deletions(-) create mode 100644 src/archive/Local Storage.md diff --git a/src/App.js b/src/App.js index 8acf3d16c..4ed77da08 100644 --- a/src/App.js +++ b/src/App.js @@ -7,20 +7,36 @@ import { TodoItem } from './TodoItem'; import { TodoButton } from './TodoButton'; import React from 'react'; -const defaultTodos = [ - { text: 'Cortar cebolla', completed: false }, - { text: 'Tomar el Curso de Intro a React.js', completed: true }, - { text: 'Usar estados derivados', completed: false }, - { text: 'Cortar berenjena', completed: false }, - { text: 'Tomar la ruta de JavaScript a pronfundidad', completed: false }, - { text: 'Llorar con la Llorona', completed: false }, - { text: 'LALALALALA', completed: false }, - {text: 'cortarte las uñas', completed: false}, -] +// const defaultTodos = [ +// { text: 'Cortar cebolla', completed: false }, +// { text: 'Tomar el Curso de Intro a React.js', completed: true }, +// { text: 'Usar estados derivados', completed: false }, +// { text: 'Cortar berenjena', completed: false }, +// { text: 'Tomar la ruta de JavaScript a pronfundidad', completed: false }, +// { text: 'Llorar con la Llorona', completed: false }, +// { text: 'LALALALALA', completed: false }, +// {text: 'cortarte las uñas', completed: false}, +// ] + +// localStorage.setItem('TODOS_V1', JSON.stringify(defaultTodos)) //añadir o crear un objeto +//localStorage.removeItem('TODOS_V1', defaultTodos) //borrar ese objeto en especifico function App() { - const [todos, setTodos] = React.useState(defaultTodos); //nuevo estado + const localStorageTodos = localStorage.getItem('TODOS_V1'); // Obtiene los datos de 'TODOS_V1' almacenados en el localStorage + + let parsedTodos; + + // Comprueba si no hay datos en el localStorage + if (!localStorageTodos){ + localStorage.setItem('TODOS_V1', JSON.stringify([]));// Establece datos iniciales si no existen en el localStorage + parsedTodos = []; // Inicializa como un arreglo vacío + } else { + parsedTodos = JSON.parse(localStorageTodos);// Si hay datos en el localStorage, los convierte de formato string a formato de arreglo usando JSON.parse() + } + + const [todos, setTodos] = React.useState(parsedTodos);// Inicializa el estado 'todos' con los datos obtenidos del localStorage o un arreglo vacío si no hay datos + const [searchValue, setSearchValue] = React.useState(''); const completedTodos = todos.filter(todo => !!todo.completed).length; @@ -43,30 +59,35 @@ function App() { } ); - const completeTodo = (text) => { // text que representa el texto de la tarea que se va a completar. - console.log('click') //Esta línea imprime 'click' en la consola cada vez que se llama a la función completeTodo. Esto podría ser útil para depurar o entender cuándo se activa esta función. - - const newTodos = [...todos]; //Crea una copia de la matriz todos utilizando el operador de propagación (...). Esto es importante para no mutar directamente la matriz original. + const saveTodos = (newTodos) => { + localStorage.setItem('TODOS_V1', JSON.stringify(newTodos));// Almacena la lista actualizada de tareas en el localStorage y actualiza la lista de tareas + setTodos(newTodos); // Actualiza la lista de tareas + }; + + const completeTodo = (text) => { + console.log('click'); // Imprime 'click' en la consola cada vez que se llama a la función + + const newTodos = [...todos]; // Crea una copia de la matriz todos const todoIndex = newTodos.findIndex( (todo) => todo.text === text - );//Encuentra el índice en el arreglo newTodos donde el texto de la tarea coincide con el argumento text proporcionado. - - newTodos[todoIndex].completed = true; //Cambia la propiedad completed de la tarea encontrada en el paso anterior a true, lo que indica que la tarea ha sido completada. - setTodos(newTodos); //Actualiza el estado de todos con la nueva matriz de tareas donde la tarea indicada se marca como completada. - } - - const deleteTodo = (text) => { - console.log('click delete') - - const newTodos = [...todos]; + ); // Encuentra el índice en la matriz newTodos donde el texto de la tarea coincide con el argumento text proporcionado + + newTodos[todoIndex].completed = true; // Marca la tarea encontrada como completada + saveTodos(newTodos); // Guarda y actualiza la lista de tareas + }; + + const deleteTodo = (text) => { + console.log('click delete'); // Imprime 'click delete' en la consola + + const newTodos = [...todos]; // Crea una copia de la matriz todos const todoIndex = newTodos.findIndex( (todo) => todo.text === text - ); - - newTodos.splice(todoIndex, 1); //Utiliza splice para eliminar un elemento en el índice todoIndex de la matriz newTodos. En este caso, se elimina un solo elemento a partir de ese índice. - setTodos(newTodos); - } - + ); // Encuentra el índice en la matriz newTodos donde el texto de la tarea coincide con el argumento text proporcionado + + newTodos.splice(todoIndex, 1); // Elimina la tarea en el índice todoIndex de la matriz newTodos + saveTodos(newTodos); // Guarda y actualiza la lista de tareas + }; + return ( // a partir de aqui no estamos incorporando html, sino JSX <> {/* → este "codigo" sin declaracion alguna es igual o hace la misma funcion que React.Fragment*/} {/* ¿ Cómo llamo a un componente? Escribiendo su nombre con la siguiente sintáxis < Componente1 /> */} diff --git a/src/archive/Local Storage.md b/src/archive/Local Storage.md new file mode 100644 index 000000000..87595c419 --- /dev/null +++ b/src/archive/Local Storage.md @@ -0,0 +1,49 @@ +>**LocalStorage** es una forma de almacenar datos en el navegador web, que persisten aún después de que el usuario haya cerrado la ventana o salido del sitio web. Es útil para guardar información del usuario, como preferencias, configuraciones, entre otros. . Los métodos más comunes de LocalStorage son: +>>- *localStorage.setItem(key, value):* Agrega un elemento con una clave y un valor al almacenamiento local. +>>- *localStorage.getItem(key):* Recupera el valor de la clave especificada en el almacenamiento local. +>>- *localStorage.removeItem(key):* Remueve un elemento del almacenamiento local según su clave. localStorage.clear(): Borra todos los elementos del almacenamiento local. + +----------EN CONCLUSION: + El Local Storage permite que se guarde la informacion de la pagina cuando el usuario borre lapestaña, la ventana del navegador o apagar su dipositivo... y aun asi cuando vuelva a la pagina, esa informacion que dejo alli se mantenga sin modificafiones hasta que el usuario lo permita + +------------------------------------------------------------------------------ + +si nosotros colocamos en la consola del navegador ↓ + +```javascript + const defaultTodos = [ + { text: 'Cortar cebolla', completed: false }, + { text: 'Tomar el Curso de Intro a React.js', completed: true }, + { text: 'Usar estados derivados', completed: false }, + { text: 'Cortar berenjena', completed: false }, + { text: 'Tomar la ruta de JavaScript a pronfundidad', completed: false }, + { text: 'Llorar con la Llorona', completed: false }, + { text: 'LALALALALA', completed: false }, + {text: 'cortarte las uñas', completed: false}, + ] + + localStorage.setItem('TODOS_V1', defaultTodos) +``` + +y luego colocamos: + + ```localStorage``` + +no nos va a aparecer el array creado TODO_V1, y si lo preguntamos directamene: + + ```localStorage.getItem('TODOS_V1')``` + +tampoco va a aparecer nada, solamente un string un poco extraño diciendo consecutivamente Object.... ya que el **localStorage** no puede guardar estructuras complejas, solamente, si o si puros *strings* +Entonces, la herramienta que utilizaremos para convertir cualquier objeto de javascript en string es ↓ + + ```JSON.stringify(defaultTodos)``` + + y para saber la cantidad de los caracteres: + + ```JSON.stringify(defaultTodos).length``` + + para tenerlo mas facil de leer: ```const stringifiedTodos = JSON.stringify(defaultTodos)``` + +Y la otra herramienta que utilizaremos para convertir stringt en objetos javascript (viceversa), es ↓ + + ```JSON.parse(stringifiedTodos)``` From f4d5775629da97bf3b21b9888412320e7481fcb6 Mon Sep 17 00:00:00 2001 From: Jairiana de Jesus Date: Tue, 2 Jan 2024 16:49:07 -0300 Subject: [PATCH 14/19] Custom Hooks --- src/App.js | 46 ++++++++++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/src/App.js b/src/App.js index 4ed77da08..5168af956 100644 --- a/src/App.js +++ b/src/App.js @@ -21,21 +21,40 @@ import React from 'react'; // localStorage.setItem('TODOS_V1', JSON.stringify(defaultTodos)) //añadir o crear un objeto //localStorage.removeItem('TODOS_V1', defaultTodos) //borrar ese objeto en especifico -function App() { - const localStorageTodos = localStorage.getItem('TODOS_V1'); // Obtiene los datos de 'TODOS_V1' almacenados en el localStorage +// Esta función maneja el uso del localStorage para un elemento específico +function useLocalStorage(itemName, initialValue) { + // Extrae el elemento del localStorage + const localStorageItem = localStorage.getItem(itemName); - let parsedTodos; + let parsedItem; // Comprueba si no hay datos en el localStorage - if (!localStorageTodos){ - localStorage.setItem('TODOS_V1', JSON.stringify([]));// Establece datos iniciales si no existen en el localStorage - parsedTodos = []; // Inicializa como un arreglo vacío - } else { - parsedTodos = JSON.parse(localStorageTodos);// Si hay datos en el localStorage, los convierte de formato string a formato de arreglo usando JSON.parse() - } + if (!localStorageItem) { + // Si no hay datos, establece el valor inicial y lo almacena en el localStorage + localStorage.setItem(itemName, JSON.stringify(initialValue)); + parsedItem = initialValue; // Establece el valor inicial + } else { + // Si hay datos en el localStorage, los convierte de formato string a formato de arreglo usando JSON.parse() + parsedItem = JSON.parse(localStorageItem); + } - - const [todos, setTodos] = React.useState(parsedTodos);// Inicializa el estado 'todos' con los datos obtenidos del localStorage o un arreglo vacío si no hay datos + // Usa React.useState para manejar el estado del item y su actualización + const [item, setItem] = React.useState(parsedItem); + + // Función para guardar un nuevo item en el localStorage y actualizar el estado + const saveItem = (newItem) => { + localStorage.setItem(itemName, JSON.stringify(newItem)); + setItem(newItem); + }; + + return [item, saveItem]; // Devuelve el estado actual del item y la función para actualizarlo +} + +function App() { + // Usa la función useLocalStorage para gestionar un elemento llamado 'TODOS_V1' en el localStorage + const [todos, saveTodos] = useLocalStorage('TODOS_V1', []); // Los corchetes vacíos indican que el valor inicial es un arreglo vacío + // 'todos' almacena el estado actual del elemento 'TODOS_V1' en el localStorage + // 'saveTodos' es la función que permite actualizar el estado de 'todos' y el localStorage const [searchValue, setSearchValue] = React.useState(''); @@ -58,11 +77,6 @@ function App() { return todoText.includes(searchText); } ); - - const saveTodos = (newTodos) => { - localStorage.setItem('TODOS_V1', JSON.stringify(newTodos));// Almacena la lista actualizada de tareas en el localStorage y actualiza la lista de tareas - setTodos(newTodos); // Actualiza la lista de tareas - }; const completeTodo = (text) => { console.log('click'); // Imprime 'click' en la consola cada vez que se llama a la función From 4defc8b6ff74759a476340a8633fcd3f479f3a68 Mon Sep 17 00:00:00 2001 From: Jairiana de Jesus Date: Wed, 3 Jan 2024 11:35:09 -0300 Subject: [PATCH 15/19] Organizacion de archivos en carpetas --- src/{css => TodoButton}/TodoButton.css | 0 src/{TodoButton.js => TodoButton/index.js} | 2 +- src/{css => TodoCount}/TodoCount.css | 0 src/{TodoCount.js => TodoCount/index.js} | 4 +--- src/{ => TodoIcon}/CompleteIcon.js | 2 +- src/{ => TodoIcon}/DeleteIcon.js | 2 +- src/{css => TodoIcon}/TodoIcon.css | 0 src/{TodoIcon.js => TodoIcon/index.js} | 2 +- src/{ => TodoIcon}/svg/check.svg | 0 src/{ => TodoIcon}/svg/delete.svg | 0 src/{css => TodoItem}/TodoItem.css | 0 src/{TodoItem.js => TodoItem/index.js} | 6 +++--- src/{css => TodoList}/TodoList.css | 0 src/{TodoList.js => TodoList/index.js} | 2 +- src/{css => TodoSearch}/TodoSearch.css | 0 src/{TodoSearch.js => TodoSearch/index.js} | 2 +- 16 files changed, 10 insertions(+), 12 deletions(-) rename src/{css => TodoButton}/TodoButton.css (100%) rename src/{TodoButton.js => TodoButton/index.js} (89%) rename src/{css => TodoCount}/TodoCount.css (100%) rename src/{TodoCount.js => TodoCount/index.js} (84%) rename src/{ => TodoIcon}/CompleteIcon.js (92%) rename src/{ => TodoIcon}/DeleteIcon.js (86%) rename src/{css => TodoIcon}/TodoIcon.css (100%) rename src/{TodoIcon.js => TodoIcon/index.js} (98%) rename src/{ => TodoIcon}/svg/check.svg (100%) rename src/{ => TodoIcon}/svg/delete.svg (100%) rename src/{css => TodoItem}/TodoItem.css (100%) rename src/{TodoItem.js => TodoItem/index.js} (83%) rename src/{css => TodoList}/TodoList.css (100%) rename src/{TodoList.js => TodoList/index.js} (80%) rename src/{css => TodoSearch}/TodoSearch.css (100%) rename src/{TodoSearch.js => TodoSearch/index.js} (97%) diff --git a/src/css/TodoButton.css b/src/TodoButton/TodoButton.css similarity index 100% rename from src/css/TodoButton.css rename to src/TodoButton/TodoButton.css diff --git a/src/TodoButton.js b/src/TodoButton/index.js similarity index 89% rename from src/TodoButton.js rename to src/TodoButton/index.js index 14d3aa865..0dca0b371 100644 --- a/src/TodoButton.js +++ b/src/TodoButton/index.js @@ -1,4 +1,4 @@ -import './css/TodoButton.css'; +import './TodoButton.css'; function TodoButton() { return ( diff --git a/src/css/TodoCount.css b/src/TodoCount/TodoCount.css similarity index 100% rename from src/css/TodoCount.css rename to src/TodoCount/TodoCount.css diff --git a/src/TodoCount.js b/src/TodoCount/index.js similarity index 84% rename from src/TodoCount.js rename to src/TodoCount/index.js index f1962463e..eb3dc0f33 100644 --- a/src/TodoCount.js +++ b/src/TodoCount/index.js @@ -1,6 +1,4 @@ -import './css/TodoCount.css'; - - +import './TodoCount.css'; function TodoCount({total, completed}){ return(

      Date: Wed, 3 Jan 2024 14:06:38 -0300 Subject: [PATCH 16/19] =?UTF-8?q?Tips=20para=20naming=20y=20abstracci?= =?UTF-8?q?=C3=B3n=20de=20componentes=20React?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App/AppUX.js | 40 +++++++++++++++++++++ src/{App.js => App/index.js} | 67 ++++++------------------------------ src/App/useLocalStorage.js | 32 +++++++++++++++++ 3 files changed, 83 insertions(+), 56 deletions(-) create mode 100644 src/App/AppUX.js rename src/{App.js => App/index.js} (65%) create mode 100644 src/App/useLocalStorage.js diff --git a/src/App/AppUX.js b/src/App/AppUX.js new file mode 100644 index 000000000..b6a10395a --- /dev/null +++ b/src/App/AppUX.js @@ -0,0 +1,40 @@ +import { TodoCount } from '../TodoCount'; +import { TodoSearch } from '../TodoSearch'; +import { TodoList } from '../TodoList'; +import { TodoItem } from '../TodoItem'; +import { TodoButton } from '../TodoButton'; + +function AppUI({ + completeTodo, + totalTodos, + searchValue, setSearchValue, + searchedTodos, + completedTodos, deleteTodo, +}) { + return ( // a partir de aqui no estamos incorporando html, sino JSX + <> {/* → este "codigo" sin declaracion alguna es igual o hace la misma funcion que React.Fragment*/} + {/* ¿ Cómo llamo a un componente? Escribiendo su nombre con la siguiente sintáxis < Componente1 /> */} + + + + + {searchedTodos.map(todo =>( + completeTodo(todo.text)} //evento del onClick del archivo TodoItem + onDelete={() => deleteTodo(todo.text)} //evento del onClick del archivo TodoItem + /> + ))} + + + + + ); +} + +export { AppUI } \ No newline at end of file diff --git a/src/App.js b/src/App/index.js similarity index 65% rename from src/App.js rename to src/App/index.js index 5168af956..672b28b79 100644 --- a/src/App.js +++ b/src/App/index.js @@ -1,11 +1,8 @@ /* eslint-disable eqeqeq */ // eslint-disable-next-line no-unused-vars -import { TodoCount } from './TodoCount'; -import { TodoSearch } from './TodoSearch'; -import { TodoList } from './TodoList'; -import { TodoItem } from './TodoItem'; -import { TodoButton } from './TodoButton'; import React from 'react'; +import { useLocalStorage } from './useLocalStorage' +import { AppUI } from './AppUX' // const defaultTodos = [ // { text: 'Cortar cebolla', completed: false }, @@ -21,35 +18,6 @@ import React from 'react'; // localStorage.setItem('TODOS_V1', JSON.stringify(defaultTodos)) //añadir o crear un objeto //localStorage.removeItem('TODOS_V1', defaultTodos) //borrar ese objeto en especifico -// Esta función maneja el uso del localStorage para un elemento específico -function useLocalStorage(itemName, initialValue) { - // Extrae el elemento del localStorage - const localStorageItem = localStorage.getItem(itemName); - - let parsedItem; - - // Comprueba si no hay datos en el localStorage - if (!localStorageItem) { - // Si no hay datos, establece el valor inicial y lo almacena en el localStorage - localStorage.setItem(itemName, JSON.stringify(initialValue)); - parsedItem = initialValue; // Establece el valor inicial - } else { - // Si hay datos en el localStorage, los convierte de formato string a formato de arreglo usando JSON.parse() - parsedItem = JSON.parse(localStorageItem); - } - - // Usa React.useState para manejar el estado del item y su actualización - const [item, setItem] = React.useState(parsedItem); - - // Función para guardar un nuevo item en el localStorage y actualizar el estado - const saveItem = (newItem) => { - localStorage.setItem(itemName, JSON.stringify(newItem)); - setItem(newItem); - }; - - return [item, saveItem]; // Devuelve el estado actual del item y la función para actualizarlo -} - function App() { // Usa la función useLocalStorage para gestionar un elemento llamado 'TODOS_V1' en el localStorage const [todos, saveTodos] = useLocalStorage('TODOS_V1', []); // Los corchetes vacíos indican que el valor inicial es un arreglo vacío @@ -103,28 +71,15 @@ function App() { }; return ( // a partir de aqui no estamos incorporando html, sino JSX - <> {/* → este "codigo" sin declaracion alguna es igual o hace la misma funcion que React.Fragment*/} - {/* ¿ Cómo llamo a un componente? Escribiendo su nombre con la siguiente sintáxis < Componente1 /> */} - - - - - {searchedTodos.map(todo =>( - completeTodo(todo.text)} //evento del onClick del archivo TodoItem - onDelete={() => deleteTodo(todo.text)} //evento del onClick del archivo TodoItem - /> - ))} - - - - + ); } diff --git a/src/App/useLocalStorage.js b/src/App/useLocalStorage.js new file mode 100644 index 000000000..b621bc978 --- /dev/null +++ b/src/App/useLocalStorage.js @@ -0,0 +1,32 @@ +import React from 'react'; + +// Esta función maneja el uso del localStorage para un elemento específico +function useLocalStorage(itemName, initialValue) { + // Extrae el elemento del localStorage + const localStorageItem = localStorage.getItem(itemName); + + let parsedItem; + + // Comprueba si no hay datos en el localStorage + if (!localStorageItem) { + // Si no hay datos, establece el valor inicial y lo almacena en el localStorage + localStorage.setItem(itemName, JSON.stringify(initialValue)); + parsedItem = initialValue; // Establece el valor inicial + } else { + // Si hay datos en el localStorage, los convierte de formato string a formato de arreglo usando JSON.parse() + parsedItem = JSON.parse(localStorageItem); + } + + // Usa React.useState para manejar el estado del item y su actualización + const [item, setItem] = React.useState(parsedItem); + + // Función para guardar un nuevo item en el localStorage y actualizar el estado + const saveItem = (newItem) => { + localStorage.setItem(itemName, JSON.stringify(newItem)); + setItem(newItem); + }; + + return [item, saveItem]; // Devuelve el estado actual del item y la función para actualizarlo +} + +export { useLocalStorage } \ No newline at end of file From 22fc25426059d6dd529497d2a267a0ec0eae6ace Mon Sep 17 00:00:00 2001 From: Jairiana de Jesus Date: Wed, 3 Jan 2024 17:52:17 -0300 Subject: [PATCH 17/19] comentarios del commit anterior --- src/App/AppUX.js | 22 +++++++++---------- src/App/index.js | 55 ++++++++++++++++++------------------------------ 2 files changed, 32 insertions(+), 45 deletions(-) diff --git a/src/App/AppUX.js b/src/App/AppUX.js index b6a10395a..52f9341a1 100644 --- a/src/App/AppUX.js +++ b/src/App/AppUX.js @@ -5,15 +5,15 @@ import { TodoItem } from '../TodoItem'; import { TodoButton } from '../TodoButton'; function AppUI({ - completeTodo, - totalTodos, - searchValue, setSearchValue, - searchedTodos, - completedTodos, deleteTodo, -}) { - return ( // a partir de aqui no estamos incorporando html, sino JSX - <> {/* → este "codigo" sin declaracion alguna es igual o hace la misma funcion que React.Fragment*/} - {/* ¿ Cómo llamo a un componente? Escribiendo su nombre con la siguiente sintáxis < Componente1 /> */} + completeTodo, // Propiedad que se espera y se asigna a la variable completeTodo + totalTodos, // Propiedad que se espera y se asigna a la variable totalTodos + searchValue, setSearchValue, // Propiedades que se esperan y se asignan a las variables searchValue y setSearchValue + searchedTodos, // Propiedad que se espera y se asigna a la variable searchedTodos + completedTodos, deleteTodo, // Propiedades que se esperan y se asignan a las variables completedTodos y deleteTodo + }) { + return ( // a partir de aqui no estamos incorporando html, sino JSX + <> {/* → este "codigo" sin declaracion alguna es igual o hace la misma funcion que React.Fragment*/} + {/* ¿ Cómo llamo a un componente? Escribiendo su nombre con la siguiente sintáxis < Componente1 /> */} completeTodo(todo.text)} //evento del onClick del archivo TodoItem - onDelete={() => deleteTodo(todo.text)} //evento del onClick del archivo TodoItem + onComplete={() => completeTodo(todo.text)} //evento del onClick del archivo TodoItem + onDelete={() => deleteTodo(todo.text)} //evento del onClick del archivo TodoItem /> ))} diff --git a/src/App/index.js b/src/App/index.js index 672b28b79..42f81b161 100644 --- a/src/App/index.js +++ b/src/App/index.js @@ -4,20 +4,6 @@ import React from 'react'; import { useLocalStorage } from './useLocalStorage' import { AppUI } from './AppUX' -// const defaultTodos = [ -// { text: 'Cortar cebolla', completed: false }, -// { text: 'Tomar el Curso de Intro a React.js', completed: true }, -// { text: 'Usar estados derivados', completed: false }, -// { text: 'Cortar berenjena', completed: false }, -// { text: 'Tomar la ruta de JavaScript a pronfundidad', completed: false }, -// { text: 'Llorar con la Llorona', completed: false }, -// { text: 'LALALALALA', completed: false }, -// {text: 'cortarte las uñas', completed: false}, -// ] - -// localStorage.setItem('TODOS_V1', JSON.stringify(defaultTodos)) //añadir o crear un objeto -//localStorage.removeItem('TODOS_V1', defaultTodos) //borrar ese objeto en especifico - function App() { // Usa la función useLocalStorage para gestionar un elemento llamado 'TODOS_V1' en el localStorage const [todos, saveTodos] = useLocalStorage('TODOS_V1', []); // Los corchetes vacíos indican que el valor inicial es un arreglo vacío @@ -33,8 +19,8 @@ function App() { const totalTodos = todos.length; //contador de todos en total - const searchedTodos = todos.filter( //estado derivado de buscar todos - (todo) => { //arrow futsion + const searchedTodos = todos.filter( //estado derivado de buscar todos + (todo) => { //arrow futsion //return todo.text.toLowerCase().includes(searchValue.toLowerCase()) //aqui estamos preguntando si por cada 'todo'; si el texto (text) de ese todo incluye (includes) en alñguna parte ese texto que forma parte del searchValue //el codigo '.toLowerCase()' convuerte toda aquellas minusculas a mayusculas y viceversa, o mejor dicho hace mas facil la busqueda de todos @@ -47,40 +33,41 @@ function App() { ); const completeTodo = (text) => { - console.log('click'); // Imprime 'click' en la consola cada vez que se llama a la función + console.log('click'); // Imprime 'click' en la consola cada vez que se llama a la función - const newTodos = [...todos]; // Crea una copia de la matriz todos + const newTodos = [...todos]; // Crea una copia de la matriz todos con '...' const todoIndex = newTodos.findIndex( (todo) => todo.text === text - ); // Encuentra el índice en la matriz newTodos donde el texto de la tarea coincide con el argumento text proporcionado + ); // Encuentra el índice en la matriz newTodos donde el texto de la tarea coincide con el argumento text proporcionado - newTodos[todoIndex].completed = true; // Marca la tarea encontrada como completada - saveTodos(newTodos); // Guarda y actualiza la lista de tareas + newTodos[todoIndex].completed = true; // Marca la tarea encontrada como completada + saveTodos(newTodos); // Guarda y actualiza la lista de tareas }; const deleteTodo = (text) => { - console.log('click delete'); // Imprime 'click delete' en la consola + console.log('click delete'); // Imprime 'click delete' en la consola - const newTodos = [...todos]; // Crea una copia de la matriz todos + const newTodos = [...todos]; // Crea una copia de la matriz todos const todoIndex = newTodos.findIndex( (todo) => todo.text === text - ); // Encuentra el índice en la matriz newTodos donde el texto de la tarea coincide con el argumento text proporcionado + ); // Encuentra el índice en la matriz newTodos donde el texto de la tarea coincide con el argumento text proporcionado - newTodos.splice(todoIndex, 1); // Elimina la tarea en el índice todoIndex de la matriz newTodos - saveTodos(newTodos); // Guarda y actualiza la lista de tareas + newTodos.splice(todoIndex, 1); // Elimina la tarea en el índice todoIndex de la matriz newTodos + saveTodos(newTodos); // Guarda y actualiza la lista de tareas }; - return ( // a partir de aqui no estamos incorporando html, sino JSX + return ( // Devuelve un elemento JSX ); + } export default App; From ae1a989d2916585ed317e9e15302022d20acb33c Mon Sep 17 00:00:00 2001 From: Jairiana de Jesus Date: Thu, 4 Jan 2024 11:52:54 -0300 Subject: [PATCH 18/19] Efectos en React --- src/App/index.js | 13 +++++- src/archive/Efectos en React.md | 73 +++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 src/archive/Efectos en React.md diff --git a/src/App/index.js b/src/App/index.js index 42f81b161..15d5f2d94 100644 --- a/src/App/index.js +++ b/src/App/index.js @@ -17,7 +17,18 @@ function App() { //segundo; se hace una arrowFutsion; '(todo => todo.completed)' se llama -todo- a aquellos todos que tengan el estado -completed- como true. Pero a simple vista se ve que va a llamar es a un valor, y nosotros necesitamos un buleano, por lo tanto se escribe con doble explamacion, para que esos valores se transformen en boleano '(todo => !!todo.completed)' //tercero; se pone la propiedad 'lwngth' para recibir las cantidades del array que se quiere filtrar const totalTodos = todos.length; //contador de todos en total - + + console.log('Log 1') + + // React.useEffect(() => { + // console.log('Log 2') + // }); // Esto se relaciona y asi la misma funcion de ASINCRONISMO DE JAVASCRIPT, primero apar4ece en la consola 'log1' 'log 3', y por ultimo apoarece el 'log 2' + + // React.useEffect(() => { + // console.log('Log 2') + // }, []); // hace exactamente la misma funcion + + console.log('Log 3') const searchedTodos = todos.filter( //estado derivado de buscar todos (todo) => { //arrow futsion diff --git a/src/archive/Efectos en React.md b/src/archive/Efectos en React.md new file mode 100644 index 000000000..5dd57e7fd --- /dev/null +++ b/src/archive/Efectos en React.md @@ -0,0 +1,73 @@ +>**PROBLEMA: LOGICA PESADA** +Hay partes de la logica de nuestros componentes que son mas complejas o pesadas. Podemos tener momentos donde partes de esa logica pueden demorarse algunos segundos (consultas a API, condicionales, etc). + +Al tener que volver a renderizar nuestro componente, toda la logica, incluso la complicada tiene que volver a renderizarse y por tanto repetir esa logica pesada. + +Si esa logica solo teniamos que aplicarla una vez, la primera renderizada, lo mejor es no tener que volverla a realizar. + +>**SOLUCION: EFECTOS EN REACT** +Los efectos son una herramienta que nos permite encapsular una logica pesada o demorada y protegerlos para que unicamente se ejecuten cuando lo necesitamos. + +Al iniciar la pagina por primera vez se ejecutan todas las funciones, pero al cambiar el estado no siempre se va a volver a correr el codigo dentro del useEffect, sino que este se volver a correr unicamente cuando cambie un estado especifico que le digamos. + +Ejemplo usando console.log + +Tenemos dentro de la logica de nuestro componente estas tres funciones de ejemplo. Una dentro de el useEffect y dos por fuera. + +``` + console.log(1) + React.useEffect(()=>{ + console.log(2) + }) + console.log(3) +``` +Los tres log aparecen, pero el ultimo en aparecer es el log 2. Al encapsularlo en el efecto: se ejecuta al final. + +*React.useEffect* recibe como primer argumento una funcion que es la logica pesada. Como segundo argumento recibe un Array, si le pasamos un Array vacio y actualizamos cualquier estado no va a volver a correr ese codigo al renderizar. Si por otro lado el Array contiene un estado o varios estados, entonces la logica se volvera a correr unicamente cuando el render sea ocasionado por cambios en esos estados que especificamos dentor del Array. + +Puede ser cualquier estado, bien sea un estado como tal o un estado derivado. + +>**CUAL ES EL USO DEL EFECTO?** +Por ejemplo si tenemos un componente que debe cargar una informacion mediante una API de manera asincrona, esta informacion tarda en llegar y mientras tanto, que pasa con nuestro componente? El usuario que observa? un mensaje cargando, un icono? + +En cambio, si usamos el efecto podemos encapsular el llamado a la API, para que ocurra al final una vez se ha cargado por primera vez nuestro componente y llame un re-renderizado para que cambie nuestro mensaje temporal de cargando…. por la informacion necesaria. + +Ademas al pasarle el Array vacio no haremos nuevos llamados innecesarios a la API + +---------------------------------------------------------------------------------------------------------------------------------------- + + +**Que son los efectos en React?** Es una función que actúa como una tarea secundaria después que el componente se haya renderizado esto es perfecto para realizar peticiones a una API que sabemos que tardaran unos algunos segundos en traerse los datos para luego montarlos en un componente para ser renderizados. También se utiliza para otras cosas como actualizar el estado de un componente, suscribirse a eventos o manipular el DOM. + +El efecto (en React el hook se llama useEffect) recibe dos parametros: + +1. Una función que define el efecto a realizar +2. Una lista de dependencias que determinan cuándo se debe volver a ejecutar el efecto. Esta lista especifica las variables que el efecto depende y si y solo si alguna de estas variables cambia entre renderizaciones, el efecto se ejecutará de nuevo. Es importante recalcar que SI NO HAY ninguna variable en la lista de dependencias, el efecto se ejecutará en cada renderización. SPOILER: React estalla XD +Un ejemplo + +``` + { + document.title = `Count is ${count}`; + }, [count]); + + function handleClick() { + setCount(count + 1); + } + + return ( +
      +

      Count: {count}

      + +
      + ); + }> +``` + +En este ejemplo, useEffect se utiliza para actualizar el título de la página con el valor actual del contador. La función de efecto se ejecuta después de cada renderizado del componente porque se ha especificado [count] como la lista de dependencias para el useEffect. Esto significa que el efecto solo se ejecutará si el valor de count ha cambiado desde la última renderización. + +Cada vez que el usuario hace clic en el botón "Increment Count", el valor de count se incrementa en 1 y se llama a la función setCount para actualizar el estado del componente. Como resultado, se vuelve a renderizar el componente y se ejecuta la función de efecto, lo que actualiza el título de la página con el nuevo valor del contador. From 7f021b8f2123a5e4c3403f2046047567e10f7567 Mon Sep 17 00:00:00 2001 From: Jairiana de Jesus Date: Fri, 5 Jan 2024 11:12:15 -0300 Subject: [PATCH 19/19] Estados de carga y error --- src/App/{AppUX.js => AppUI.js} | 7 +++++++ src/App/index.js | 20 ++++++++----------- src/App/useLocalStorage.js | 36 +++++++++++++++++++++------------- 3 files changed, 37 insertions(+), 26 deletions(-) rename src/App/{AppUX.js => AppUI.js} (75%) diff --git a/src/App/AppUX.js b/src/App/AppUI.js similarity index 75% rename from src/App/AppUX.js rename to src/App/AppUI.js index 52f9341a1..795b77174 100644 --- a/src/App/AppUX.js +++ b/src/App/AppUI.js @@ -5,6 +5,8 @@ import { TodoItem } from '../TodoItem'; import { TodoButton } from '../TodoButton'; function AppUI({ + loading, //recibimos como prop + error, //recibimos como prop completeTodo, // Propiedad que se espera y se asigna a la variable completeTodo totalTodos, // Propiedad que se espera y se asigna a la variable totalTodos searchValue, setSearchValue, // Propiedades que se esperan y se asignan a las variables searchValue y setSearchValue @@ -21,6 +23,11 @@ function AppUI({ /> + {loading &&

      Estamos cargando...

      } {/*mensaje que aparecera si se esta cargando */} + {error &&

      Hubo un error.

      } {/* mensaje que aparecera si hay un error */} + {(!loading && searchedTodos.length == 0) &&

      Crea tu primer TODO

      } + {/* (si no se esta cargando y la longitud de los todos es igual a 0) entonces aparecera un mensaje que dira 'crea tu todo' */} + {searchedTodos.map(todo =>( { - // console.log('Log 2') - // }); // Esto se relaciona y asi la misma funcion de ASINCRONISMO DE JAVASCRIPT, primero apar4ece en la consola 'log1' 'log 3', y por ultimo apoarece el 'log 2' - - // React.useEffect(() => { - // console.log('Log 2') - // }, []); // hace exactamente la misma funcion - - console.log('Log 3') const searchedTodos = todos.filter( //estado derivado de buscar todos (todo) => { //arrow futsion @@ -69,6 +63,8 @@ function App() { return ( // Devuelve un elemento JSX { //ahora es asincrona (se demorara) + // Extrae el elemento del localStorage + const localStorageItem = localStorage.getItem(itemName); + + let parsedItem; - // Comprueba si no hay datos en el localStorage + // Comprueba si no hay datos en el localStorage if (!localStorageItem) { // Si no hay datos, establece el valor inicial y lo almacena en el localStorage localStorage.setItem(itemName, JSON.stringify(initialValue)); @@ -16,17 +21,20 @@ function useLocalStorage(itemName, initialValue) { // Si hay datos en el localStorage, los convierte de formato string a formato de arreglo usando JSON.parse() parsedItem = JSON.parse(localStorageItem); } - - // Usa React.useState para manejar el estado del item y su actualización - const [item, setItem] = React.useState(parsedItem); + }); - // Función para guardar un nuevo item en el localStorage y actualizar el estado - const saveItem = (newItem) => { - localStorage.setItem(itemName, JSON.stringify(newItem)); - setItem(newItem); - }; + // Función para guardar un nuevo item en el localStorage y actualizar el estado + const saveItem = (newItem) => { + localStorage.setItem(itemName, JSON.stringify(newItem)); + setItem(newItem); + }; - return [item, saveItem]; // Devuelve el estado actual del item y la función para actualizarlo + return { + item, + saveItem, + loanding, + error + }; // si tenemos mas de DOS ELEMENTOS que queremos RETORNAR dentro de los CustomHoocks; es mucho mas recomendable que enviemos un objeto{} que un array() } export { useLocalStorage } \ No newline at end of file