// Reto: crea un componente <ListaTareas /> que:
// - Permita escribir una tarea en un input y agregarla con un formulario.
// - Muestre las tareas en una lista.
// - Permita marcar/desmarcar una tarea como completada al hacer clic.
// - No agregue tareas vacías.
//
// Tests: lista-tareas.test.tsx — intenta resolverlo antes de leer la solución de abajo.
import { useRef, useState, type FormEvent } from "react";
// Tipar la forma de los datos es lo primero en React + TS:
// el resto del componente se apoya en este tipo.
type Tarea = {
id: number;
texto: string;
completada: boolean;
};
export function ListaTareas() {
// useState<Tarea[]> es necesario: con solo [] TypeScript inferiría never[].
const [tareas, setTareas] = useState<Tarea[]>([]);
const [texto, setTexto] = useState("");
// Un ref como contador de ids: sobrevive entre renders sin provocar re-renders.
const siguienteId = useRef(1);
function agregar(evento: FormEvent<HTMLFormElement>) {
evento.preventDefault();
const limpio = texto.trim();
if (!limpio) return;
// Nunca mutamos el arreglo: creamos uno nuevo con spread.
setTareas((previas) => [
...previas,
{ id: siguienteId.current++, texto: limpio, completada: false },
]);
setTexto("");
}
function alternar(id: number) {
// map devuelve un arreglo nuevo; el objeto modificado también es nuevo.
setTareas((previas) =>
previas.map((t) =>
t.id === id ? { ...t, completada: !t.completada } : t
)
);
}
return (
<div>
<form onSubmit={agregar}>
<input
value={texto}
onChange={(e) => setTexto(e.target.value)}
placeholder="Nueva tarea"
/>
<button type="submit">Agregar</button>
</form>
<ul>
{tareas.map((tarea) => (
// La key debe ser estable y única: usamos el id, nunca el índice.
<li
key={tarea.id}
onClick={() => alternar(tarea.id)}
data-completada={tarea.completada}
>
{tarea.completada ? `✔ ${tarea.texto}` : tarea.texto}
</li>
))}
</ul>
</div>
);
}