A煤n no tienes acceso a esta clase

Crea una cuenta y contin煤a viendo este curso

Completando y eliminando TODOs

11/23
Recursos

Aportes 62

Preguntas 19

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesi贸n.

Por favor, un curso intermedio y uno avanzado con este mismo profe. Es muy simple y claro a la vez.

Yo me tome el atrevimiento y cambie el m茅todo completeTodo() por toggleCompleteTodo() para permitir que destilde de completado alg煤n TODO que le marco completado sin querer. De esta forma sigue funcionando todo y me parece m谩s genial para el usuario por si se confunde.
.
La soluci贸n me quedo asi:

const toggleCompleteTodos = (text) => {
	const todoIndex = todos.findIndex(todo => todo.text === text);
	const newTodos = [...todos];
	newTodos[todoIndex].completed = !newTodos[todoIndex].completed;
	setTodos(newTodos);
}

Hasta ahora, excelente curso BatiProfe 馃槂

Otra forma de borrar los todos

function deleteTodo(text){
    const newTodos = todos.filter(todo=>todo.text !== text)
    setTodos(newTodos)
  }

Para cambiar el icono de la tarea es muy sencillo:

Mandamos por props una propiedad donde mandemos por valor todo.complete (es el mapeo del nuevo array que se creo la clase pasada de toda la informaci贸n de los todos)

Y en el componente TodoItem traer ese prop y hacer un if ternario como en la siguiente imagen y listo! Espero haber ayudado 馃槂

La mejor frase que puedo escuchar de Juan es decir: "Entonces, recapitulemos鈥"
Todos los profesores deber铆an hacer esto para poder juntar toda la informaci贸n en nuestro cerebro de forma m谩s f谩cil

As铆 va quedando mi Todo-Machine 馃敟


Le a帽ad铆 un bot贸n para editar Todos 馃

  • Luego lo mejorare con un Modal


.

necesitamos mas cursos como este

Hola, trate de optimizar el c贸digo y permitir al usuario cambiar entre completo o no. Qued贸 as铆:

  const findIndex = (text) => {
    return todos.findIndex(todo => todo.text === text)
  }

  const toggleTodo = (text) => {

    const newTodos = [...todos]
    newTodos[findIndex(text)].completed = !newTodos[findIndex(text)].completed
    setTodos(newTodos)
  }

  const deleteTodo = (text) => {

    const newTodos = [...todos]
    newTodos.splice(findIndex(text), 1)
    setTodos(newTodos)
  }

Porfa que el curso de avanzado lo dicte JUAN DAVID los otros profesores son buenos pero hablan como si uno ya supierta todo en cambio Juan te lleva de la mano y sin darte cuenta est谩s entiendiendolo todo!

Para quienes no les funcione, cambie el nombre de la propiedad onComplete por complete y onDelete por delete (cambiarlo por otro, pero con on lo probre varias veces y no me funciono) , me funciono de esta manera.

<TodoList>

        {searchTodos.map(todo => (          
          <TodoItem 
            key={todo.text} 
            text={todo.text}
            completed={todo.completed}
            complete={() => completeTodo(todo.text)}
            delete={() => deleteTodo(todo.text)}
          />
        ))}    

me tome el atrevimiento de hacer una verificacion. Cuando un todo no este completado no se pueda eliminar!

Algo 煤til, ser铆a permitirle al usuario poder quitar el to-do como completado. Para hacer esto, basta con colocar

newTodos[todoIndex].completed = ! newTodos[todoIndex].completed

El cual servir谩 de toggler, donde si se hace click y est谩 marcado como completado, lo desmarcar谩 y quedar谩 sin completar.

Yo originalmente ya hab铆a usado un 铆ndice en la TodoList:

<TodoList>
        {searchedTodos.map((todo, index) => (
          <TodoItem
            text={todo.text}
            key={index}
            completed={todo.completed}
            onComplete={() => completeTodo(index)}
            onDelete={() => deleteTodo(index)}
          />
        ))}
</TodoList>

Por lo que en vez de buscar por texto (ya con esto podemos tener 2 o m谩s elementos con mismo texto) podemos buscar por 铆ndice:

const completeTodo = (index) => {
    const newTodos = [...todos]
    newTodos[index].completed = !newTodos[index].completed
    setTodos(newTodos)
  }

  const deleteTodo = (index) => {
    const newTodos = [...todos]
    newTodos.splice(index, 1)
    setTodos(newTodos)
  }

Les dejo una muestra de los avances que tengo hasta el momento 馃コ

Yo le pase los todos y el setTodo al item y desde ahi resolvi la logica de la siguiente forma, pudiendo marcar y desmarcar el todo por si lo marcaste por error y aun no lo habias completado, yo mismo hice los svg para no utilizar iconos y/o imagenes

function TodoItem({text, completed, todos, setTodos}) {
  const onComplete = () => {
    let actualizarTodos = [] 
    if(completed) {
      actualizarTodos = todos.map(item => {
        if(text === item.text) {
          item.completed = false;
        }
        return item;
      })
    } else {
      actualizarTodos = todos.map(item => {
        if(text === item.text) {
          item.completed = true;
        }
        return item;
      })
    }
    setTodos(actualizarTodos);
  }
  const onDelete = () => {
    setTodos(todos.filter(item => item.text !== text))
  }

  return (
    <li className="TodoItem">
      <svg 
        className={`iconCheck ${completed && 'iconCheck--active'}`}
        height="40"
        width="40"
        onClick={onComplete}
      >
       <path d="M 25 13 A 10 10 0 1 0 30 20 m 0 0 z M 15 20 l 5 5 L 33 10 " />
      </svg>
      <p className={`TodoItemText ${completed && 'TodoItemText--completed'}`}>{text}</p>
      <svg
        className={`iconDump ${completed && 'iconDump--active'}`}
        height="40"
        width="40"
        onClick={onDelete}
      >
       <path d="M 8 10 L 32 10 m 0 0 z M15 10 l 0 -3 l 2 -2 l 6 0 l 2 2 l 0 3 z" />
       <path d="M10 15 l 20 0 l -3 20 l -14 0 l -3 -20" />
       <path d="M15 18 l 1 14 z M 20 18 l 0 14 z M 25 18 l -1 14" />
      </svg>
    </li>
  )
}

export { TodoItem };

con un IF en la funcion completeTodos de App.js, puedes volver a destachar un TODO tachado(algo b谩sico, pero por si lo necesitan:

const completeTodos = (text) => {
    const todoIndex = todos.findIndex(todo => todo.text === text);
    const newTodos = [...todos];
    if(todos[todoIndex].completed === false){
      todos[todoIndex].completed = true;
    } else{
      todos[todoIndex].completed = false;
    }
    setTodos(newTodos);
  };

Me pareci贸 interesante poder hacer que el 铆cono de check funcione como un toggle (un bot贸n que se activa y desactiva) por lo que agreg煤e un condicional dentro de nuestra funci贸n:

const toggleCompleteTodos = (text) =>
  {
    const todoIndex = todos.findIndex(task=> task.text == text);
    const newTodos = [...todos];
    if(newTodos[todoIndex].completed == false) // Si nuestro valor es falso, lo cambiamos a true
    {
      newTodos[todoIndex].completed = true;
    }
    else // caso contrario, va false :)
    {
      newTodos[todoIndex].completed = false;
    }
    setTodos(newTodos);
  }

Never stop learning 鈾

Una cosa interesante que me paso antes de ver la resoluci贸n del video fue la de clonar el vector todos, no se si sera algo trivial pero cuento lo que me paso por si alguno le sirve.

//en mi caso la llame as铆  y recibe la posicion del vector
 const finishTodo = (id) => {
        todos[id].completed = true;
        let aux = todos;
        setTodos(aux);
    };

si hacia esta asignaci贸n

let aux = todos;

no se realizaba el cambio de estado en la pagina de forma autom谩tica
en cambio al hacerlo como el profesor si funcionaba instant谩neamente.

let aux = [...todos];

Investigando un poco, creo que esto se debe a la forma en que js copia los arrays. De la anterior forma se copiaba una referencia y de la segunda se hacia una copia real del array.
Dejo una guia en donde lo explican de mejor manera
https://www.kuworking.com/javascript-como-copiar-arrays

//permite completar y descompletar un todo
  const completeTodos = (text) => {
    setTodos(
      todos.map((todo) =>
        todo.text === text ? { ...todo, completed: !todo.completed } : todo
      )
    );
  };

//eliminando todo
  const deleteTodos = (text) => {
    setTodos(todos.filter((todo) => todo.text !== text));
  };

Podemos modificar la funci贸n completeTodos para que podamos volver a marcarlo como incompleto, en caso de que nos equivoquemos o que al fin resulte que no completamos efectivamente ese ToDo jeje

    const toggleCompleteTodo = (text) => {
        const todoIndex = todos.findIndex(todo => todo.text == text);
        const newTodos = [...todos];

        newTodos[todoIndex].completed = !newTodos[todoIndex].completed

        setTodos(newTodos)
    }

Tambi茅n podemos simplificar la funci贸n deleteTodo con el m茅todo filter, que retorna un nuevo array:

const deleteTodo = (text) => {
        setTodos(
            todos.filter(todo => todo.text != text)
        )
    }

Es mas f谩cil as铆, solo le pasas el 铆ndice y ya 炉_(銉)_/炉:

(task, i) => <TodoItem ... onCheck={() => updateItemCheck(i)} />

profe si que explicas bien.

Con lo visto en esta clase y los aported de otros compa帽eros le reduje a mi solucion como 8 lineas de codigo :'v

Para la funci贸n de deleteTodo yo no la hice con splice, la hice con filter:

const deleteTodo(text) => {
  const removeTodo = todos.filter((todo) => todo.text !== text);
  setTodos(leftTodos);
}

Por aqu铆 les dejo un peque帽o aporte para reducir un poco nuestro c贸digo鈥

agrege una funcion de los mas sencilla para poner el item de "todo check"despues de un click en verdadero, con dos click denuevo en falso.

import React from "react";
import './TodoItem.css';
function TodoItem(props){
    return(
        <li className="TodoItem">
            <span className= {`Icon Icon-check ${props.completed && 'Icon-check--active'}`}
            onClick={props.onComplete} onDoubleClick={props.noComplete}
            ></span>
            <p className={`TodoItem-p ${props.completed && 'TodoItem-p--complete'}`}
          
            >
            {props.text}
                </p>
            <span className="Icon Icon-delete"   onClick={props.onDelete}
            >
            <ion-icon name="trash-outline"></ion-icon>
             
                </span>
        </li>
    );
}

export { TodoItem };

codigo de app

import React from 'react';
import { TodoCounter } from './TodoCounter';
import { TodoSearch } from './TodoSearch';
import { TodoList } from './TodoList';
import { TodoItem } from './TodoItem';
import { CreateTodoButton } from './CreateTodoButton';
// import './App.css';

const defaultTodos = [
  { text: 'Cortar cebolla', completed: true },
  { text: 'Tomar el cursso de intro a React', completed: false },
  { text: 'Llorar con la llorona', completed: true },
  { text: 'LALALALAA', completed: false },
];

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;

  let searchedTodos = [];

  if (!searchValue.length >= 1) {
    searchedTodos = todos;
  } else {
    searchedTodos = todos.filter(todo => {
      const todoText = todo.text.toLowerCase();
      const searchText = searchValue.toLowerCase();
      return todoText.includes(searchText);
    });
  }
  const completeTodos = (text)=> {
    const todoIndex = todos.findIndex(todo =>todo.text === text);
    const newTodos = [...todos];
     newTodos[todoIndex].completed = true;
    setTodos(newTodos);
  
  };
  const descompleteTodos = (text)=> {
    const todoIndex = todos.findIndex(todo =>todo.text === text);
    const newTodos = [...todos];
     newTodos[todoIndex].completed = false;
    setTodos(newTodos);
  };
  const deleteTodo = (text) => {
    const todoIndex = todos.findIndex(todo => todo.text === text);
    const newTodos = [...todos];
    newTodos.splice(todoIndex, 1);
    setTodos(newTodos);
  };
  return (
    <React.Fragment>
      <TodoCounter
        total={totalTodos}
        completed={completedTodos}
      />
      <TodoSearch
        searchValue={searchValue}
        setSearchValue={setSearchValue}
      />

      <TodoList>
        {searchedTodos.map(todo => (
          <TodoItem
            key={todo.text}
            text={todo.text}
            completed={todo.completed}
            onComplete={() => completeTodos(todo.text)}
            noComplete={() => descompleteTodos(todo.text)}
            onDelete={() => deleteTodo(todo.text)}
          />
        ))}
      </TodoList>

      <CreateTodoButton />
    </React.Fragment>
  );
}

export default App;

el problema es que no se si el ondbclick es mala practica de esa manera por que pensaba hacerlo con if pero asi es mas sencillo.

He notado que al usar solo todos cuando queremos marcar una tarea completada y sin usar el array de **newTodos **para **setTodos(todos) ** el componente del Item de React no se re-renderiza. Solo cuando hago un cambio en el codigo.

const todoIndex = todos.findIndex(todo => todo.text === text);
    todos[todoIndex].completed = true;
    setTodos(todos);

Interesante. Eso me hace pensar un poco en como React renderiza los componentes, todavia no tengo la certeza pero seguro que lo veremos en el curso. 馃槃


completando y eliminando todos
aprendiendo a elegir y modificar cambios

隆Hola! Les comparte mi funci贸n para borrar cosas, usa filter en lugar de lo que David us贸, funciona igual pero es ligeramente m谩s cortito 馃槃

	const deleteTodo = (text) => {
		const newTodos = todos.filter(todo => todo.text !== text);
		setTodos(newTodos);
	};

Mi practica

App.js

import React from 'react';
import {v4 as uuidv4} from 'uuid';
import {TodoCounter, TodoSearch, TodoList, TodoItem, CreateTodoButton} from "./components";
// import logo from './logo.svg';
//import './App.css';

const defaultTodos = [
    {id: uuidv4(), text: 'Cortar cebolla', completed: false},
    {id: uuidv4(), text: 'Tomar el curso', completed: true},
    {id: uuidv4(), text: 'Ir a dormir', completed: false},
];

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;
    let searchedTodos = [];
    if (searchValue.length >= 1) {
        searchedTodos = todos.filter(todo => {
            let todoText = todo.text.toLowerCase();
            let searchText = searchValue.toLowerCase()
            return todoText.includes(searchText);
        });
    } else {
        searchedTodos = todos;
    }

    const toggleCompleteTodos = (id) => {
        const todoIndex = todos.findIndex(todo => todo.id == id);
        const newTodos = [...todos];

        (newTodos[todoIndex].completed === false)
            ? newTodos[todoIndex].completed = true
            : newTodos[todoIndex].completed = false;

        setTodos(newTodos);
    };
    const deleteTodo = (id) => {
        const todoIndex = todos.findIndex(todo => todo.id == id);
        const newTodos = [...todos];
        console.log(newTodos);
        newTodos.splice(todoIndex,1);
        console.log(newTodos);
        setTodos(newTodos);
    };

    return (
        <React.Fragment>
            <TodoCounter
                completed={completedTodos}
                total={totalTodos}
            />
            <TodoSearch
                searchValue={searchValue}
                setSearchValue={setSearchValue}
            />
            <TodoList>
                {searchedTodos.map(todo => (
                    <TodoItem
                        key={todo.id}
                        text={todo.text}
                        completed={todo.completed}
                        onToggleComplete={() => toggleCompleteTodos(todo.id)}
                        onDelete={()=>deleteTodo(todo.id)}
                    />
                ))}
            </TodoList>

            <CreateTodoButton/>
        </React.Fragment>
    );
}

export default App;

TodoItem.js

import React from 'react';
import './TodoItem.css';
import CheckBoxIcon from '@mui/icons-material/CheckBox';
import CheckBoxOutlineBlankIcon from '@mui/icons-material/CheckBoxOutlineBlank';
import CloseIcon from '@mui/icons-material/Close';

function TodoItem(props) {
    const onToggleComplete = props.onToggleComplete;
    const onDelete = props.onDelete;


    return (
        <li className="TodoItem">
            <span
                className={`Icon Icon-check ${props.completed && 'Icon-check--active'}`}
                onClick={onToggleComplete}
            >
                {
                    props.completed
                        ? <CheckBoxIcon/>
                        : <CheckBoxOutlineBlankIcon/>
                }

            </span>
            <p className={`TodoItem-p ${props.completed && 'TodoItem-p--complete'}`}>{props.text}</p>
            <span
                className="Icon Icon-delete"
                onClick={onDelete}
            ><CloseIcon/></span>
        </li>
    )
}

export {TodoItem};

esta es mi solucion para cambiar el eliminar todos

  const deleteTodo = (text) => {
    const updatedTodos = todos.filter( todo => todo.concept !== concept)
    settodos(updatedTodos)
  }

Muy buenas estas clases, con estas explicaciones, me gust贸 lo del pan tajado jajaja.

Otra forma de hacerlo鈥 es pasarle el index desde .map

searchTasks.map( (task, index) => (
    <TodoItem key={task.id} task={task} 
                              changeCompleteTask={() => changeCompleteTask(index)}
                              delTask={() => delTask(index)} />
            ))

Les comparto mi progreso con un dise帽o con una paleta de colores similar a la de Platzi 馃槃
.

no me sorprenderia si mi profe a los 30 a帽os es el nuevo elon musk

Para poder marcar y desmarcar un Todo (a veces hacemos missclick o nos distraemos y marcamos el que no era) solo es poner una condicional que verifiqu茅 si tiene estado 鈥渇alse鈥 lo cambie a 鈥渢rue鈥 o viceversa. 馃榾

  const completeTodo = (text) => {
    const todoIndex = todos.findIndex(todo => todo.text === text);
    const newTodos = [...todos];

//La condicional es la siguiente:
    newTodos[todoIndex].completed === false ? newTodos[todoIndex].completed = true : newTodos[todoIndex].completed = false;    
    setTodos(newTodos);
  }

Me gusta escribir las variables globales en may煤sculas, para no confundirme e identificarlas rapidamente.

Intent茅 crear estados individuales por cada todo en sus atributos 鈥榗ompleted鈥 y 鈥榙eleted鈥. Pero para hacerlo deb铆a crear un nuevo componente dentro del componente que ya ten铆a, dado que no dejaba crear los Hooks. El objetivo era ejecutar la actualizaci贸n desde el mismo componente 鈥楲ist Item鈥. Observ茅 que no pod铆a actualizar los estados originales, supongo por lo que estos estados realmente no estaban dentro de App, sino de cada 鈥業tem鈥, y s铆, se guardaban los valores de los estados (encapsulamiento? 馃え), pero no quedaban registrados en los Todos originales. Prob茅 copiar la lista de Todos y modificar la nueva lista, para luego usar 鈥榮et鈥, pero me gener贸 un error por muchos Renders. En conclusi贸n, no es buena idea JAJAJA 馃ぃ

Dejo el c贸digo para que se hagan un idea del enredo! 馃憞

  function LoadTodosListItem (todo) {
    const [completed, setCompleted] = React.useState(todo.completed);
    const [deleted, setDeleted] = React.useState(todo.deleted);
    
    return (
      <TodoItem key={todo.text} text={todo.text} completed={completed} setCompleted={setCompleted} deleted={deleted} setDeleted={setDeleted} color={todo.color} todos={todos} setTodos={setTodos} />
    )
  }

Y鈥

      <TodoList>
        {searchedTodos.map(todo => LoadTodosListItem(todo))}
      </TodoList>

Que clase tan genial

no me salio T.T
pero estoy feliz

Otra forma de hacer el toggle:

const toggleTodo = (text) => {
  const todoIndex = todos.findIndex((todo) => todo.text === text);
  setTodos((prev) => {
    prev[todoIndex].completed = !prev[todoIndex].completed;
    return [...prev];
  });
};

La funci贸n setTodos del react recibe por par谩metro un valor prev interno, ese valor es un estado previo de todos, por lo que se puede trabajar sobre ese mismo valor sin necesidad de crear una nueva variable.
S铆, es un poco m谩s complejo, pero es otra forma (?)

Otra forma de hacer deleteTodo

const deleteTodo = (text) => {
  setTodos((prevTodo) =>
    prevTodo.filter((todo) => !todo.text.includes(text))
  );
};

setTodo toma prevTodo como par谩metro propio que retorna el estado anterior de todos. Se pasa un arrow function y se filtra para que retorne los todo que no incluyan el texto.

As铆 es como me queda usando las librer铆as de SweetAlert2 y para ello debes ejecutar en la terminal o CMD el comando:
npm install --save sweetalert2 sweetalert2-react-content

y despu茅s para el tema oscuro de las alertas:
npm install @sweetalert2/theme-dark


Por 煤ltimo en los componentes de 鈥.js鈥 debes importarlos, en App.js importas:
import 鈥楡sweetalert2/theme-dark鈥;

En los componentes donde vallas a mostrar la alerta importas:
import Swal from 鈥渟weetalert2鈥;

En estos ejemplos, estas son una parte de mi c贸digo de las alertas:

const completeTodo = (text) => {
const todoIndex = todos.findIndex(todo => todo.text === text);
const newTodos = [...todos];
Swal.fire({
  title: "驴Marcar Todo?",
  background: "#000",
  showCancelButton: true,
  confirmButtonColor: "#31b904",
  cancelButtonColor: "#d30404",
  cancelButtonText: "NO",
  confirmButtonText: "S脥",
  footer: text
}).then((result) => {
  if (!!result.value) {
    newTodos[todoIndex].completed = true;
    setTodos(newTodos);
  }
})
};


const deleteTodo = (text) => {
const todoIndex = todos.findIndex(todo => todo.text === text);
const newTodos = [...todos];
Swal.fire({
  icon: 'question',
  title: "驴Eliminar Todo?",
  background: "#000",
  confirmButtonColor: "#d30404",
  showCancelButton: true,
  cancelButtonColor: '#31b904',
  cancelButtonText: "NO",
  confirmButtonText: "S脥",
  footer: text
}).then((result) => {
  if (!!result.value) {
    newTodos.splice(todoIndex, 1);
    setTodos(newTodos);
  }
})

};

Este curso es buenisimo!!! D:

Hasta este momento , un excelente curso de React, no puedo esperar para segui con el proximo!!!

Con este c贸digo extra la funci贸n completeTodo tambi茅n habilita el desmarcar como hechos los 鈥榯odos鈥

const completeTodo = (text) => {
const todoIndex = todos.findIndex(todo => todo.text === text)
const newTodos = [鈥odos]
if(!newTodos[todoIndex].completed) {
newTodos[todoIndex].completed = true
} else {
newTodos[todoIndex].completed = false
}
setTodos(newTodos)
}

Juan contagia la felicidad cuando corre bien la aplicaci贸n jajajaja

A mi me gusta m谩s enviar en props el objeto completo, en ocasiones te ahorra enviar m煤ltiples propiedades. En este caso como trabajamos con todas las propiedades del todo creo que conviene mucho.
Ejemplo:

 <TodoItem key={todo.text} todo={todo}
                            completeTodo={completeTodo}
                            deleteTodo={deleteTodo}
                  />

Para completar el todo se simplifica la funci贸n:

const completeTodo = (todo) => {
    let index = todos.indexOf(todo);
    let newTodos = [...todos];
    newTodos[index].completed=true;
    setTodos(newTodos);
  }

Y en el componente trabajas con el 鈥渙bjeto鈥 que te interesa:

 <span className={`Icon Icon-check ${props.todo.completed && 'Icon-check--active'}`}
                onClick={onComplete}
          >

Mi solucion

  const [completed, setCompleted] = useState(props.completed);

  const handleComplete = (event) => {
    event.target.checked ? setCompleted(true) : setCompleted(false);
  };

Tambien se puede hacer una forma mas simplificada en deleteTodo:

const deleteTodo = (text) => {
  const newTodos = todos.filter(todo => todo.text !== text);

  setTodos(newTodos);
}

De esta forma no buscamos el indice ni nada. Simplemente creamos un nuevo array con la funcion filter, con los todos que tengan un texto diferente al que le enviamos por parametro.

Otra alternativa de resolver el mismo problema:

const completeTodos = text => {
setTodos(prev => prev.map(todo => todo.text === text
		? {...todo, completed: true}
		: todo
	))
}
const deleteTodos = text => {
	setTodos(prev => prev.filter(todo => todo.text !== text))
}

Esta forma de utilizar el codigo, es util cuando estamos haciendo una App de TODOs con POO

    todos[todoIndex] = {
      text: todos[todoIndex].text,
      completed:true,
    };

Recien termine el curso de POO con Anncode y mi mente visualiza todo en modo 鈥淥bjetos鈥

Hice lo mismo que el compa帽ero lucas y de verdad que le agrega mucha funcionalidad a la app por si nos llegamos a equivocar y marcamos una tarea como completada cuando a煤n no est谩 completa馃ゴ

Aqu铆 dejo el c贸digo:
En App.js

En TodoItem.Js

Que bueno por el profesor que se tomo la molestia de explicar muy detalladamente la funcion completeTodos.

Excelente el filtro

隆Lo logr茅, consegu铆 crear mi bot贸n para eliminar TODOS!

https://github.com/luiznaiper/react-platzi-proyect-1.git

Lo que hice fue filtrar los TODOS que tuvieran la propiedad completada como falso y actualic茅 el estado:

const deleteCompletedTodos = ()=> {
    const filterTodos = todos.filter(todo => todo.completed === false)
    console.log(filterTodos)
    setTodos(filterTodos)
  }
      <ClearCompletedButton
        total = { totalTodos }
        completed={ completedTodos }
        deleteCompletedTodos={ ()=> deleteCompletedTodos()}
      />

Me cost贸 much铆simo pero se logr贸

No es tan necesario y 煤til usar el text, y buscar con filter en cada operaci贸n, con el index del .map() se hubiera podido editar eliminar el todo directamente con su index.

Pueda que haya sido por alguna raz贸n que desconozco pero tambi茅n se pod铆a sacar en 鈥渋ndex鈥 a la hora de iterar con el m茅todo 鈥渕ap鈥.

<TodoList>
        {searchedTodos.map((todo, index) => (
          <TodoItem
            key={todo.id} 
            text={todo.text} 
            completed={todo.completed} 
            completar={() => completeTask(index)}
            remover={() => removeTask(index)} />
        ))}
      </TodoList>

Metodos:

 const completeTask = (index) => {
    const newTodos = [...todos];
    newTodos[index].completed = true;
    setTodos(newTodos);
  }

  const removeTask = (index) => {
    const newTodos = [...todos];
    newTodos.splice(index,1);
    setTodos(newTodos);
  }
const completeTodo = (text) => {
    const todoIndex = todos.findIndex(todo => todo.text === text);
    const newTodos = [...todos];
    newTodos[todoIndex].completed = true;
    updateTodo(newTodos);
  };

  const deleteTodo = (text) => {
    const todoIndex = todos.findIndex(todo => todo.text === text);
    const newTodos = [...todos];
    newTodos.splice(todoIndex, 1);
    updateTodo(newTodos);
  };

Yo hice diferente en borrado (usando filter), les dejo mi funci贸n espero les sirva.

const deleteTodo = ( text ) => {
    const newTodos = todos.filter( todo => todo.text !== text );
    setTodos(newTodos);
  };

As铆 los elimin茅 todos y con menos l铆neas de c贸digo, no se si ser谩 correcto

const deleteTodo = (text) => {
    const todoFilter = todos.filter(todo => todo.text !== text)
    setTodos(todoFilter)
  }

Saludos Platzinautas.
Lo que hice fue, las variables completeTodos y totalTodos los lleve abajo, despues de la funcion if/else, y cambie los contadores de todos por searchedTodos

Eureka鈥 funciona鈥 super, muchas gracias鈥

Siento cosquillitas鈥