No tienes acceso a esta clase

隆Contin煤a aprendiendo! 脷nete y comienza a potenciar tu carrera

Curso de React.js

Curso de React.js

Juan David Castro Gallego

Juan David Castro Gallego

Contando TODOs

8/34
Recursos

Aportes 60

Preguntas 7

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad?

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

Agradecido de que hayan quitado el curso de React anterior de Oscar Barajas, era toda una tortura 炉_(銉)_/炉

Hola JD, cuando dices que no se puede compartir estados de un componente hijo a un padre, claro indicas 鈥淎l 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 鈥淓stado鈥 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 鈥淓stado鈥 dentro del Componente Padre (En este caso App.js) para poder comunicarlo al componente hijo a trav茅s de 鈥減rops鈥 (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

鈥淓ntonces, 驴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:

  • Los estados son un tipo de variables de React, especialmente optimizadas en la dinamica de sus valores dentro del programa y a su efecto en el DOM o** interfaz.**
  • Como los estados son variables como tal, pueden tener otras variables que broten de su base,** los estados derivados**

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;

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 鈥渢odos鈥 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}  />
Hola, tengo una duda. ![](https://static.platzi.com/media/user_upload/imagen-413ba4d3-46d3-4900-a745-6b58762f665e.jpg) la constante completedTodos recibe un valor del todos.filter, al momento de agregar un nuevo elemento al array se ejecutara el filter pasandole otro valor a la constante, esto no generaria un error ya que no se le puede reasignar otro valor a la constante, quien puede explicarme por favor.

mi solucion al nuevo estado derivado de totalTodos fue :
const totalTodos = todos.filter((todo) => !!defaultTodos).length;

jejejejej el camino m谩s largo posible

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>

Desmostraci贸n

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 />
    </>
  );
}
Pero completedTodos y totalTodos no son reactivos, si borras un registro de la lista el totalTodos no se actualiza lo mismo con el completed

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.

Este reto me saco canas pero asi lo logre, primero en app.js le pase el valor convertido en minusculas atraves del props como hicimos anteriormente el nombre ![](https://static.platzi.com/media/user_upload/image-4195026d-bc9d-4bf0-a4cd-4ea489805890.jpg) ![](https://static.platzi.com/media/user_upload/image-4c0e0fcc-b693-44a5-a7f0-62ba10db8fab.jpg) Luego en todoItem.js lo que hice fue capturarlo y con condicionales devolver el valor , primero creamos las variables : ![](https://static.platzi.com/media/user_upload/image-f8024304-849b-4db3-9033-eb694d1b8763.jpg) y ya con la utilizacion del booleano, cuando busque algo igual al props.text va a devolver el \
  • como lo hicimos al inicio, y si el booleano es false ("cuando el props text es diferente o esta vacio") solo hace return de \

    vacio ![](https://static.platzi.com/media/user_upload/image-69f5e83c-9ae4-41ba-9fe4-151c63fcfd37.jpg)

  • Mi forma de resolver el reto para que me de la cantidad de Todos que hay en total: ![](https://static.platzi.com/media/user_upload/image-ca98cb09-3a8f-4ab3-8e91-64c2fbb0c884.jpg)
    Me encanta este profesor, ojal谩 todo el mundo ense帽ara as铆, de f谩cil y poni茅ndose en el lugar del alumno. Eres un m谩quina Juan David!
    Mi soluci贸n al reto `const totalTodos = todos.filter(todo => !!todo).length;`
    ```js const totalTodos = todos.length; ``` const totalTodos = todos.length;

    Contando TODOs

    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

    Buscando la longitud

      const totalTodos = defaultTodo.length;
    
    

    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鈥o 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 鈥渟olucion鈥 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鈥檚 a partir del texto, pero la soluci贸n me evit贸 muchos errores de consola. Fue divertido.

    p茅sima la edici贸n, el profe ocupa casi 1/4 de la pantalla siendo que lo importante para mi es apreciar bien el c贸digo
    Reto completado, lo que use fue filtrar el texto ingresado por el usuario con los todos, y si hay coincidencias retorne un array y con ese array es el que se itera para mostrar los componentes, Tambien aplice lowecase a ambas partes para hacerlo indiferente a mayusculas o minusculas ```js const FilterTodos = todos.filter(({text}) => { return text.toLowerCase().includes(searchValue.toLowerCase()) }) <ItemsContainer> {FilterTodos.map(({text, completed}) => { return <Item text={text} completed={completed} /> })} </ItemsContainer> ```![](https://static.platzi.com/media/user_upload/image-80f6aa09-fb5b-4614-ab9b-8c99efec41ee.jpg)![](https://static.platzi.com/media/user_upload/image-d317e036-f1d9-4cd4-bbfa-119262a898c4.jpg) ![](https://static.platzi.com/media/user_upload/image-42c550b8-51e1-412d-a81c-330629ec547d.jpg)
    ```js const totalTodos = todos.length ```Con la longitud del array inicial
    Cantidad de todos... yo los llam茅 taks: 聽const totalTask= tasks.filter(聽 聽 task => task).length;
    Para mostrar el total de los Todos, fue super f谩cil. pero no se si ser谩 la mejor manera. solo use el m茅todo length de los arrays en el array de los Todos ![](https://static.platzi.com/media/user_upload/aaaaaa-b11c39e5-79f6-4cda-ad44-c7548820d9be.jpg)
    Excelente
    ![](https://static.platzi.com/media/user_upload/imagen-485205e7-27ee-460d-8eb7-c71e10674337.jpg)

    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.

    Comunicaci贸n de 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);
          }}
        />
      );
    }
    

    Estados Derivados

    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}/>
    

    Contando TODOs (compartir informacion entre componentes)

    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.

    Declarar y enviar el State y SetState

    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;
    

    Recibir el State en el component hijo

    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 };
    
    As铆 consegu铆 la totalidad de Todo's `const allTodos = todos.filter(todo => !!todo.ready.valueOf).length;`
    ![](https://static.platzi.com/media/user_upload/imagen-cba60c5b-d8d1-4aa9-b678-17e989ec5f71.jpg)
    Dios primero, Dios les bendiga. Pues si dijimos que vamos a retornar el .lenght de mi array de completed y ese es el valor n煤merico que retorno para que me salgan los todos completados pues la misma l贸gica pero con todo el array independientemente del valor de los completed. Entonces: const totalTodos = todos.length聽
    No se puede compartir estados desde un componente hijo a un componente padre a traves de una funci贸n callback? O.o

    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 (鈥楶endiente鈥 o 鈥淐ompletado鈥)

    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