import { useState } from "react"; type Lesson = { id: string; title: string; done: boolean }; const initial: Lesson[] = [ { id: "html", title: "HTML 表单", done: false }, { id: "css", title: "CSS 布局", done: true }, ]; export default function App() { const [lessons, setLessons] = useState(initial); const [draft, setDraft] = useState(""); const [query, setQuery] = useState(""); const [onlyPending, setOnlyPending] = useState(false); const [error, setError] = useState(""); const word = query.trim().toLocaleLowerCase(); const visible = lessons.filter(item => (!onlyPending || !item.done) && item.title.toLocaleLowerCase().includes(word)); function add() { const title = draft.trim(); if (!title) { setError("请输入学习内容"); return; } setLessons(current => [...current, { id: crypto.randomUUID(), title, done: false }]); setDraft(""); setError(""); } function toggle(id: string) { setLessons(current => current.map(item => item.id === id ? { ...item, done: !item.done } : item)); } return

学习记录板

{ event.preventDefault(); add(); }}> setDraft(event.target.value)} aria-describedby={error ? "input-error" : undefined} />
{error && }

显示 {visible.length} 项,待学 {lessons.filter(item => !item.done).length} 项

{visible.length === 0 ?

没有匹配的记录

: }
; }