Skip to content

Workshop: React + 3 Essential Hooks

React Todo List (Refactor from Chapter 2)

Refactor Todo List จาก Vanilla JS (Chapter 2) มาเป็น React app เต็มรูปแบบ ใช้ useState จัดการ state, useEffect สำหรับ localStorage persistence, และ useMemo สำหรับ filter optimization พร้อม style ด้วย Tailwind CSS + shadcn/ui
  • Refactor Todo List จาก Vanilla JS เป็น React components
  • ใช้ useState จัดการ todos, input, และ filter state
  • ใช้ useEffect อ่าน/เขียน localStorage
  • ใช้ useMemo สำหรับ filter todos (All / Active / Completed)
  • Style ด้วย Tailwind CSS + shadcn/ui components
What you'll build Preview
React Todo List
What needs to be done?
Add
Learn useState ×
Learn useEffect ×
Build FilterBar component ×
Add useMemo optimization ×

  • Directoryreact-todo/
    • Directorysrc/
      • App.jsx
      • Directorycomponents/
        • TodoItem.jsx
        • TodoForm.jsx
        • FilterBar.jsx
    • package.json

  1. สร้างโปรเจกต์ React + Tailwind

    Section titled “สร้างโปรเจกต์ React + Tailwind”

    ใช้ Vite สร้างโปรเจกต์ใหม่ แล้วติดตั้ง Tailwind CSS และ shadcn/ui

    Terminal window
    npm create vite@latest react-todo -- --template react
    cd react-todo
    npm install

    ติดตั้ง Tailwind CSS ตาม Tailwind docs แล้วเพิ่ม shadcn/ui ถ้าต้องการ

  2. สร้าง component หลักที่เก็บ state ทั้งหมด — todos array, input text, และ filter mode ใช้ useState สำหรับทุก state

    const [todos, setTodos] = useState([]);
    const [input, setInput] = useState("");
    const [filter, setFilter] = useState("all");
  3. เพิ่ม localStorage ด้วย useEffect

    Section titled “เพิ่ม localStorage ด้วย useEffect”

    เขียน useEffect สองตัว:

    • ตัวแรก: อ่าน todos จาก localStorage ตอน mount (dependency array ว่าง [])
    • ตัวที่สอง: บันทึก todos ลง localStorage ทุกครั้งที่ todos เปลี่ยน
  4. แยก form สำหรับเพิ่ม todo ออกเป็น component แยก รับ input, setInput, และ onAddTodo เป็น props

  5. แยก todo แต่ละตัวเป็น component รับ todo, onToggle, และ onDelete เป็น props แสดง checkbox, text, และปุ่ม delete

  6. สร้าง FilterBar component สำหรับเลือก filter (All / Active / Completed) แล้วใช้ useMemo ใน App.jsx เพื่อคำนวณ filteredTodos จาก todos + filter

    const filteredTodos = useMemo(() => {
    switch (filter) {
    case "active": return todos.filter((t) => !t.completed);
    case "completed": return todos.filter((t) => t.completed);
    default: return todos;
    }
    }, [todos, filter]);
  7. Style ด้วย Tailwind + ทดสอบ

    Section titled “Style ด้วย Tailwind + ทดสอบ”

    ใส่ Tailwind classes ให้ทุก component ให้สวยงาม ทดสอบว่า:

    • เพิ่ม/ลบ/toggle todo ได้
    • Filter ทำงานถูกต้อง
    • Refresh แล้ว todos ยังอยู่ (localStorage)
    • UI สวยงามและ responsive