Es raro estar en un curso desde el principio 😅. Por lo general los comentarios que veo son de hace uno o dos años. Ahora literal veo tres comentarios(10/05/23). HOLA GENTE DEL FUTURO uwu
Introducción y requisitos
¿Qué necesitas para aprender React.js?
Maquetación con React.js
¿Qué es un componente?
Componentes de TODO Machine
¿Cómo se comunican los componentes? Props y atributos
Estilos CSS en React
Interacción con React.js
Eventos en React: onClick, onChange
¿Qué es el estado?
Contando TODOs
Buscando TODOs
Completando y eliminando TODOs
Librería de Iconos Personalizados
Iconos en React: librerías y SVG
Iconos con colores dinámicos
Herramientas avanzadas: escalabilidad, organización y persistencia
Local Storage con React.js
Custom Hooks
Organización de archivos y carpetas
Feature-First Directories en React
Tips para naming y abstracción de componentes React
¿Qué son los efectos en React?
Estados de carga y error
Actualizando estados desde useEffect
Reto: loading skeletons
¿Qué es React Context?
useContext
¿Qué son los React Portals?
Reto: estados para abrir y cerrar un modal
Maquetando formularios en React
Crear TODOs: React Context dentro de React Portals
Deploy
Despliegue de TODO Machine en GitHub Pages
Presentación de proyectos para tu portafolio
Próximos pasos: React #UnderTheHood
Diferencias entre versiones de React.js
¿Cuándo realmente necesitas React.js?
Bonus: creando proyectos en React desde cero
React con Create React App
React con Next.js
React con Vite
No tienes acceso a esta clase
¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera
Convierte tus certificados en títulos universitarios en USA
Antes: $249
Paga en 4 cuotas sin intereses
Termina en:
Juan David Castro Gallego
Aportes 66
Preguntas 7
Es raro estar en un curso desde el principio 😅. Por lo general los comentarios que veo son de hace uno o dos años. Ahora literal veo tres comentarios(10/05/23). HOLA GENTE DEL FUTURO uwu
Hola JD, cuando dices que no se puede compartir estados de un componente hijo a un padre, claro indicas “Al menos por ahora” te refieres a que es poco recomendable hacerlo? ósea sí se puede, de una forma un poco ortodoxa pero yo lo logré utilizando un useEffect. no sé si sea lo recomendado y qué problemas puede llegar a tener.
export const ComponenteHijo = ({onChange}) =>{
const [state, setState] = useState('valor inicial')
useEffect(()=>{
onChange(state)
},[state])
}
y en el componente padre lo recibo así:
export const ComponentePadre = () =>{
return (
<>
<ComponenteHijo onChange={ (e) => console.log(e) } />
</>
)
}
ya defino si el valor del evento onChage, lo almaceno en otro estado del padre o decido hacer una lógica distinta, pero si obtengo un valor de un estado que puede cambiar.
¿Cómo comunico informacion de mi estado entre componentes?
…
Podemos comunicar informacion del “Estado” entre componentes utilizando las "props" pero hay que tener en cuenta que esa informacion la podemos compartir Solamente de "Componentes Padres a Componentes Hijos."
Es decir, debemos declarar el “Estado” dentro del Componente Padre (En este caso App.js) para poder comunicarlo al componente hijo a través de “props” (TodoSearch.js)
Ando en un Bootcamp Fullstack y ya tenia la suscripción a Platzi desde hace 6 meses pausada porque no la estaba utilizando y ya había empezado el Bootcamp y que grata sorpresa ver este curso de React porque aunque mi profe del Bootcamp es un teso , soy de las personas que tiene que ver una clase mas de 1 vez para aprender y como Juan lleva la clase pasito a pasito como si le explicara a un niño de primaria me ha parecido muy bueno
Así lo abordé, con un ternario, sin hacer cambios de estado.
Vamos a ver si era asi 👀
JAJAJAAJA no pude evitar morirme de risa en el momento en que Juan dice
“Entonces, ¿Cómo compartimos el estado de un componente hijo a un padre?. La respuesta es clara… No se puede”
JAJAJAJJA
Excelente explicación; una de las mejores clases que he visto. Gracias
Entonces podemos verlo asi:
para el reto de filtrar los todos lo realicé tal que así:
// Estado para el search value
const [searchValue,setSearchValue] = React.useState('');
// filtrar los todos
const filteredTodos = defaultTodos.filter(todo =>
todo.text.toLowerCase().includes(searchValue.toLowerCase())
);
lo que hago es que dentro de la función de flecha, se verifica si el texto de cada tarea (todo.text) incluye el valor de búsqueda (searchValue). Para evitar problemas de mayúsculas/minúsculas y asegurar una comparación insensible a ellas, tanto el texto de la tarea como el valor de búsqueda se convierten a minúsculas utilizando el método toLowerCase().
Si el valor de búsqueda está contenido en el texto de la tarea (ignorando mayúsculas/minúsculas), la expresión todo.text.toLowerCase().includes(searchValue.toLowerCase()) devolverá true, lo que significa que la tarea cumple con la condición de filtrado
y dentro del TodoList hago lo siguiente:
{filteredTodos.map(todo => (
<TodoItem
key={todo.text}
text={todo.text}
completed={todo.completed}
/>
))}
y por ultimo: , la expresión {filteredTodos.map(todo => … )} se encarga de iterar sobre las tareas filtradas y renderizar un componente <TodoItem>
Para contar el total de TODOs lo que hice fue un simple length del array
const completedTodos = todos.filter(item => {
return item.completed === true;
}).length;
const totalTodos = todos.length;
Como ya definimos el useState
por defecto simplemente:
const totalTodos = todos.length;
Y nuestro todoCounter
:
<TodoCounter
completed={completedTodos} total={totalTodos} />
Juan mis felicitaciones es increible lo que hiciste con la fabrica de react ojala conviertan la mayor parte de las clases semejante a estas saludo y sigue cosechando exito
Para obtener la cantidad de TODOs de manera simple
const totalTodos = todos.length;
vacio ![](https://static.platzi.com/media/user_upload/image-69f5e83c-9ae4-41ba-9fe4-151c63fcfd37.jpg)
Buscando la longitud
const totalTodos = defaultTodo.length;
No entiendo a quien se le ocurrio enseñar a principiantes programacion con JavaScript. LLevo años programando y puedo decir que este lenguaje es para niveles intermedios a avanzados.
Como “todos” es un array, le paso su tamaño a totalTodos
const totalTodos = todos.length;
Y este valor lo envio al componente TodoCounter
<TodoCounter todosCompleted={completedTodos} totalTodos={totalTodos} />
mi solucion al nuevo estado derivado de totalTodos fue :
const totalTodos = todos.filter((todo) => !!defaultTodos).length;
jejejejej el camino más largo posible
No hagan esto
!!myVariable
usen
Boolean(myVariable)
La respuesta es clara… No se puede
JASJAJSas
fue una súper clase 😃
function App() {
const [todos, setTodos] = React.useState(defaultTodos);
const [searchValue, setSearchValue] = React.useState('');
const completedTodos = todos.filter(todo => !!todo.completed).length;
const totalTodos = todos.length;
console.log('El usuario esta buscando ' + searchValue);
return (
<>
<TodoCounter
completedTodos={completedTodos}
totalTodos={totalTodos}/>
<TodoSearch
searchValue={searchValue}
setSearchValue={setSearchValue}
/>
<TodoList>
{defaultTodos.map(todo => (
<TodoItem
key={todo.text}
text={todo.text}
completed={todo.completed}
/>
))}
</TodoList>
<CreateTodoButton />
</>
);
}
import React, { useState, useEffect } from 'react';
import { TodoCounter } from './TodoCounter';
import { TodoSearch } from './TodoSearch';
import { TodoList } from './TodoList';
import { TodoItem } from './TodoItem';
import { CreateTodoButton } from './CreateTodoButton';
import { Nadvar } from './Nadvar';
import { Footer } from './Footer';
import { Graficos } from './Graficos';
import './App.css';
const defaultTodos = [
{ 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: 'LALA', completed: false },
];
const frasesMotivacionales = [
"Cree en ti, todo es posible.",
"El éxito es la suma de esfuerzos.",
"La perseverancia lleva a la victoria.",
"Si puedes soñarlo, puedes lograrlo.",
"El cambio comienza con una decisión.",
"Crea, rompe, aprende, repite, evoluciona, persiste.",
"Cada día es una nueva oportunidad.",
"Persiste con fuerza, la meta te espera.",
"Si puedes imaginarlo, puedes crearlo.",
'Código limpio: como arte, simple y efectivo.',
"Debuggear es el arte de ser paciente.",
"La mejor documentación es un código claro.",
"Programar es como resolver un rompecabezas.",
"No reinventes la rueda, a menos que aprendas.",
"Códigos buenos son poesía, no aburridos prosa.",
"Siempre hay espacio para mejorar tu código.",
"Piensa antes de programar, después hazlo simple.",
"Escribe código que otros amen leer.",
];
function App() {
//TodoSearch input
const [searchValue, setSearchValue] = React.useState(''); //estado inicia en '' y se va actualizar
console.log(searchValue);
//TodoCounter P1 has completado N de N TODOs
const [todos, setTodos] = React.useState(defaultTodos);
const completedTodos = todos.filter(
todo=> !!todo.completed //me va a indicar solo si es verdadero
).length; //esto solo me dara el total de los todos completados
const totalTodos = todos.length;
//TodoCounter P2 Frases random
const [motivationalPhrase, setMotivationalPhrase] = React.useState(''); //actual y atualización
const generateRandomMotivationalPhrase = () => {//función con la actualización la frase random
const randomPhrase = frasesMotivacionales[Math.floor(Math.random() * frasesMotivacionales.length)];
setMotivationalPhrase(randomPhrase);
};
useEffect(() => {//estado que hace posible el reenderizado
generateRandomMotivationalPhrase();
}, []); // Este efecto se ejecutará una vez al montar el componente
return (
// Ract.Fragments = <> </>
<>
<Nadvar/>
<TodoCounter
completed={completedTodos}
total={totalTodos}
motivationalPhrase={motivationalPhrase}
/>
<TodoSearch
searchValue={searchValue}
setSearchValue={setSearchValue}
/>
<div className="container">
<TodoList>
{defaultTodos.map(todo => (
<TodoItem
key={todo.text}
text={todo.text}
completed={todo.completed}
/>))}
</TodoList>
<Graficos/>
</div>
<CreateTodoButton/>
<Footer/>
</>
);
}
export default App;
Explicación del código
El proposito es saber el total de Todos completados y el total de todos para poder renderizarlos
Entonces lo que se va hacer es ver como vamoos a obtener esos datos
Tenemos el array con los datos
const defaultTodos = [
{ 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: 'LALA', completed: false },
];
Creamos el estado que renderiza el estado inicial y actualiza los datos, por default tendrá los datos del array como estado inicial
Creamos una variable donde vamos a obtener el valor de los TODOs completados
Creamos una variable con el total de todos los TODOs
//TodoCounter P1 has completado N de N TODOs
const [todos, setTodos] = React.useState(defaultTodos);
const completedTodos = todos.filter(
todo=> !!todo.completed //me va a indicar solo si es verdadero
).length; //esto solo me dara el total de los todos completados
const totalTodos = todos.length;
Pasamos los valores al componente
<TodoCounter
completed={completedTodos}
total={totalTodos}
motivationalPhrase={motivationalPhrase}
/>
Me encanta este curso todo muy claro, estoy aprendiendo mucho espero pronto encontrar nuevos cursos de buena calidad como este
Hola puedes poner el curso que dices de manipulacion de Arrays con Javascript por favor 😃 Gracias muy buena forma de explicar.
modo simple:
const totalTask = task.length;
O.O! Increible, esta nueva actualización me ha gustado tanto que porfin puedo decir que estoy entendiendo React. Que buen profe, me quito el sombrero. lol
buen video
Para la cantidad de tareas completadas y cantidad total lo hice de esta manera
Como dato a modo de practica sirve mucho esta aplicación de RunJs para hacer pruebas sobre todo en objetos y manipulación del mismo
Intenté hacer el reto pero no sé como implementar este filter en los componentes…lo intenté pero no lo logré.
const filterTaskInput = countTask.filter(tasks => ( //filtrar las tareas según input
tasks.text.includes(searchValue,0)
));
Respecto al reto la respuesta ya estaba a la vista, solo era un length al array inicial.
Esta es mi “solucion” para el reto del filtro de Todos. No es la mas eficiente, pero funciona. XD
Ahora solo estoy pensando como implementarla para que se muestre en React.
const filter = todos.filter(item => item.name.includes(searchValue));
Mi solución fue que que la siguiente
function App() {
const [todos, setTodos] = React.useState(defaultTodos);
const [searchValue, setSearchValue] = React.useState("");
const completedTodos = todos.filter((todo) => !!todo.completed).length;
const totalTodos = todos.length;
console.log(`los usuarios buscan todos de ${searchValue}`);
return (
<>
<TodoCounter completed={completedTodos} total={totalTodos} />
<TodoSearch
searchValue={searchValue}
setSearchValue={setSearchValue}
/>
<TodoList>
{defaultTodos.map((todo) => (
<TodoItem
key={todo.text}
text={todo.text}
completed={todo.completed}
/>
))}
</TodoList>
<CreateTodoButton />
</>
);
}
const totalToDos = ToDos.filter(ToDo => !!ToDo.text).length;
Funcionó hacer esto, por que sabía que leería todos los ToDo’s a partir del texto, pero la solución me evitó muchos errores de consola. Fue divertido.
{props.text}
{props.text}\
\\
\En la clase anterior, aprendimos a gestionar estados en React y creamos nuestro primer estado, el estado del componente TodoSearch
, para almacenar el valor que los usuarios escriben en el campo de búsqueda. En esta clase, nos enfocaremos en cómo comunicar estados entre componentes padres e hijos y cómo crear estados derivados para realizar cálculos basados en otros estados.
No es posible enviar estados directamente de un componente hijo a un componente padre en React. La comunicación de estados se realiza de padres a hijos. Para solucionar esto, utilizaremos la combinación de props
y estados.
En el componente padre (TodoApp
), creamos un estado llamado searchValue
y su actualizador setSearchValue
. Este estado se envía como propiedades (searchValue
y setSearchValue
) al componente hijo TodoSearch
. De esta manera, TodoSearch
puede acceder y actualizar este estado.
// En TodoApp.js
const [searchValue, setSearchValue] = useState('');
// ...
<TodoSearch searchValue={searchValue} setSearchValue={setSearchValue} />
// En TodoSearch.js
function TodoSearch({ searchValue, setSearchValue }) {
return (
<input
placeholder="Buscar TODO"
className="TodoSearch"
value={searchValue}
onChange={(event) => {
setSearchValue(event.target.value);
}}
/>
);
}
Además, aprendimos a crear estados derivados, que son cálculos basados en otros estados. En nuestro caso, creamos dos estados derivados en el componente TodoCounter
: completedTodos
y totalTodos
. Estos estados derivados se calculan a partir del estado original todos
.
// En TodoApp.js
const [todos, setTodos] = React.useState(defaultTodos);
const completedTodos = todos.filter(todo => !!todo.completed).length;
const totalTodos = todos.length;
En este ejemplo, completedTodos
se filtra para incluir solo los todos completados (todo.completed
es true
). La longitud de todos
se utiliza para calcular totalTodos
.
Estos estados derivados pueden ser enviados como props a otros componentes para su uso.
// En TodoApp.js
<TodoCounter completed={completedTodos} total={totalTodos} />
// En TodoCounter.js
function TodoCounter({ total, completed }) {
return (
<h1 className='TodoCounter'>
Completaste <span>{completed}</span> de <span>{total}</span> TODOs
</h1>
);
}
Con estos conceptos, logramos que nuestro contador de todos funcione correctamente, mostrando la cantidad de todos completados y la cantidad total de todos.
En la próxima clase, abordaremos cómo implementar la búsqueda de todos, permitiendo que lo que escriben los usuarios en TodoSearch
determine qué todos se muestran en la lista. ¡Buena suerte!
const totalTodos = todos.length;
<TodoCounter completed={completedTodos} total={totalTodos}/>
La forma de compartir informacion entre componentes es mediante props, los props son informacion que un componente padre envia al hijo en forma de objeto o variables.
Pero por defecto no se puede enviar informacion del hijo al padre, por esto se debe crear un State de React en el componente padre y enviarlo junto con su metodo Set al componente hijo, mediante props, asi, el hijo lo recibe y lo puede usar y mediante Set modificarlo y se modificara en toda la aplicacion, donde se encuentre.
function App() {
// se definie el state
const [searchValue, setSearchValue] = React.useState('');
return (
<>
<TodoSearch
{/* se envia el State y su metodo Set para que el hijo pueda usarlo*/}
searchValue={searchValue}
setSearchValue={setSearchValue}
/>
</>
);
}
export default App;
import React from 'react'
// Se recibe el estado mediante props
function TodoSearch({ searchValue, setSearchValue}) {
return (
<input
placeholder="Cortar cebolla"
className="TodoSearch"
{/* Aqui se utiliza el estado */}
value={searchValue}
onChange={(e) => {
{/* Aqui se modifica el state mediante Set, y se modificara y rerenderizara
en todos los lugares de la app donde este */}
setSearchValue(e.target.value)
}}
/>
);
}
export { TodoSearch };
Yo lo solucione asi: cree un nuevo array:
let [todos, setTodos]= useState(array)
// Filtra el array 'todos' basado en el valor de 'search'
const filteredTodos = todos.filter(todo => {
// Verifica si la tarea incluye la palabra introducida en 'search'
return todo.tarea.toLowerCase().includes(search.toLowerCase());
});
return (
<div className="background-image">
<div className="todo-list-container">
<TodoCounter tasks={reducedResult.totalTasks} completed={reducedResult.completedTasks}/>
<TodoSearch
search={search} setSearch={setSearch}
/>
<TodoList />
{filteredTodos.map(todo => ( //usamos el estado inicial de los todos para renderizarlos
<TodoItem key={todo.tarea} texto={todo.tarea} state={todo.estado}/>
))}
...
y le pase como props al TodoItem el texto y el estado de la tarea (‘Pendiente’ o “Completado”)
Buenas, yo hice el curso de manipulacion de arrays, y use reduce para obtener la cantidad de tareas completadas:
...
let [todos, setTodos]= useState(array)
//Funcion para obtener la estadistica de cantidad de completados y totales
const reducedResult = todos.reduce((accumulator, currentTask) => {
accumulator.totalTasks++;
if (currentTask.estado === 'Completado') {
accumulator.completedTasks++;
}
return accumulator;
}, { totalTasks: 0, completedTasks: 0 });
return (
<div className="background-image">
<div className="todo-list-container">
<TodoCounter tasks={reducedResult.totalTasks} completed={reducedResult.completedTasks}/>
<TodoSearch
search={search} setSearch={setSearch}
/>
...
hola desde el futuro, jajaja
const totalTodos=todos.filter(()=>defaultTodos).length;
pues asi
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?