Resumen

Lograr que una aplicación de to-dos en React responda cuando el usuario marca una tarea como completada o la borra es uno de los pasos más satisfactorios del desarrollo. Aquí se construyen las dos funciones clave —completeTodo y deleteTodo— directamente en el componente App.js, se explica cómo respetar la inmutabilidad del estado y se conecta todo con los componentes hijos mediante props.

¿Cómo marcar un to-do como completado en React?

El punto de partida es crear una función llamada completeTodo dentro de App.js [00:08]. Esta función recibe como parámetro el texto del to-do, que actúa como identificador único: cada tarea debe tener un texto diferente para que el sistema funcione correctamente.

Dentro de la función se utiliza el método findIndex [01:05]. Este método recorre el array de to-dos y evalúa, elemento por elemento, cuál cumple la condición todo.text === text. Cuando lo encuentra, devuelve la posición (el index) dentro del array. Hay un detalle importante que menciona el linter de React: las comparaciones deben hacerse con triple igual (===) en lugar de doble igual (==) para evitar coerciones de tipo inesperadas [06:44].

Una vez obtenido el index, no se puede modificar el estado directamente. React necesita recibir un nuevo array para disparar un re-render. Aquí entra en juego el spread operator (...) [03:56]: se crea una copia del array original con const newTodos = [...todos], se modifica la propiedad completed del elemento correspondiente a true, y finalmente se llama a setTodos(newTodos) para actualizar el estado.

js const completeTodo = (text) => { const todoIndex = todos.findIndex(todo => todo.text === text); const newTodos = [...todos]; newTodos[todoIndex].completed = true; setTodos(newTodos); };

¿Por qué no se puede editar el estado directamente?

React depende de las funciones setter como setTodos para saber cuándo debe volver a renderizar los componentes [03:30]. Si se muta el array original sin pasar por el setter, React no detecta el cambio y la interfaz no se actualiza. Por eso siempre se clona el array, se hacen los cambios en la copia y se envía esa copia al estado.

¿Cómo se conecta la función con el componente TodoItem?

Desde App.js se pasa una prop llamada onComplete al componente TodoItem [05:15]. Esta prop es una arrow function que llama a completeTodo con el texto del to-do correspondiente:

jsx <TodoItem onComplete={() => completeTodo(todo.text)} />

Dentro de TodoItem, el evento onClick del botón de check invoca props.onComplete. Al hacer clic, el to-do aparece en verde y con el texto tachado, y el TodoCounter se actualiza automáticamente porque la cantidad de completados cambió [07:15].

¿Cómo eliminar un to-do con el método splice?

La función deleteTodo sigue una lógica muy parecida [08:18]. Recibe el texto, busca el index con findIndex y clona el array. La diferencia está en que, en lugar de cambiar una propiedad, se utiliza el método splice para remover el elemento.

El método splice espera dos argumentos [09:00]: la posición desde donde se empieza a cortar y la cantidad de elementos a eliminar. Se usa la analogía de un pan tajado: se coloca el cuchillo en la tajada indicada por todoIndex y se saca exactamente una tajada.

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

Después se pasa la prop onDelete al componente TodoItem de la misma forma que onComplete [10:12]. En el componente hijo, el botón con la X ejecuta props.onDelete al recibir un clic.

¿Qué pasa con la persistencia de datos?

Al probar la aplicación, tanto completar como borrar funcionan perfectamente: el contador se actualiza, los estilos cambian y los elementos desaparecen de la lista [10:50]. Sin embargo, al recargar la página los cambios se pierden, porque el estado solo vive en memoria. La solución se aborda en el módulo de persistencia con localStorage [07:50].

Con estas dos funciones la aplicación ya cubre las operaciones de completar y eliminar. Solo queda implementar la creación de nuevos to-dos para tener el ciclo completo. ¿Ya intentaste construir la función de agregar por tu cuenta antes de ver la siguiente clase?