ခဏလေး ဒီလိုပဲ စဉ်းစားကြည့်
Part 1 မှာ static data နဲ့ layout ပဲရှိခဲ့ပါတယ်၊ Part 2 မှာတော့ user က တကယ် interact လုပ်လို့ရတဲ့ app ဖြစ်လာအောင် logic ထည့်ပါမယ်။ Form တစ်ခုကနေ task အသစ် type ရိုက်ထည့်ခြင်း၊ submit event ကို handle လုပ်ခြင်း၊ setTasks နဲ့ state ကို immutably update လုပ်ခြင်းတွေကို လေ့ကျင့်ရပါလိမ့်မယ်။ Task တစ်ခုချင်းစီရဲ့ done status ကို toggle လုပ်ခြင်းနဲ့ ဖျက်ခြင်းလည်း TaskItem ကနေ event ကို parent ဆီ callback အနေနဲ့ ပြန်ပို့ရပါမယ်။ ဒီအဆင့်ကတော့ project ရဲ့ core value ဖြစ်တဲ့ "user data ကို interactive အနေနဲ့ manage လုပ်ခြင်း" အပိုင်းဖြစ်ပါတယ်။
လက်တွေ့ ဆောက်ကြည့်မယ်
TaskTracker component ထဲမှာ form တစ်ခုနဲ့ input field တစ်ခု ထည့်ပါ - controlled input အနေနဲ့ useState တစ်ခု ထပ်ကြေညာပါ။ handleSubmit function မှာ event.preventDefault() ခေါ်ပြီး input value ကို tasks array ထဲကို {id: Date.now(), text, done: false} အဖြစ် setTasks([...tasks, newTask]) နဲ့ ထည့်ပါ။ TaskItem ကို onToggle နဲ့ onDelete callback props နှစ်ခု ပေးပို့ပြီး၊ checkbox click event နဲ့ delete button click event ကနေ parent ရဲ့ function ကို ခေါ်ပါ။ toggle function မှာ .map() နဲ့ id တူတဲ့ task ရဲ့ done ကိုပဲ ပြောင်း၊ delete function မှာ .filter() နဲ့ id မတူတဲ့ task တွေကိုပဲ ထားပါ။
Code နမူနာ
// src/components/TaskTracker.jsx
import { useState } from "react";
import TaskItem from "./TaskItem";
function TaskTracker() {
const [tasks, setTasks] = useState([
{ id: 1, text: "Learn React basics", done: true },
]);
const [text, setText] = useState("");
function handleSubmit(e) {
e.preventDefault();
if (!text.trim()) return;
const newTask = { id: Date.now(), text, done: false };
setTasks([...tasks, newTask]);
setText("");
}
function toggleTask(id) {
setTasks(
tasks.map((task) =>
task.id === id ? { ...task, done: !task.done } : task
)
);
}
function deleteTask(id) {
setTasks(tasks.filter((task) => task.id !== id));
}
return (
<div className="task-tracker">
<h2>My Tasks</h2>
<form onSubmit={handleSubmit}>
<input
value={text}
onChange={(e) => setText(e.target.value)}
placeholder="Add a new task..."
/>
<button type="submit">Add</button>
</form>
<ul>
{tasks.map((task) => (
<TaskItem
key={task.id}
task={task}
onToggle={() => toggleTask(task.id)}
onDelete={() => deleteTask(task.id)}
/>
))}
</ul>
</div>
);
}
export default TaskTracker;
// src/components/TaskItem.jsx
function TaskItem({ task, onToggle, onDelete }) {
return (
<li className={task.done ? "task-item done" : "task-item"}>
<input type="checkbox" checked={task.done} onChange={onToggle} />
<span>{task.text}</span>
<button onClick={onDelete}>Delete</button>
</li>
);
}
export default TaskItem;Input box ထဲ text ရိုက်ပြီး Add နှိပ်ရင် task list ထဲကို ချက်ချင်းထပ်ပေါ်လာပြီး၊ checkbox click လုပ်ရင် strikethrough ပြောင်း၊ Delete နှိပ်ရင် list ကနေ ချက်ချင်းပျောက်သွားပါလိမ့်မယ်။၅ မိနစ် စမ်းကြည့်
Task text field ကို empty string ဖြစ်နေရင် Add button ကို disabled attribute နဲ့ click မရအောင် ပြောင်းကြည့်ပါ - 5 minutes အတွင်း ပြီးအောင် လုပ်ကြည့်ပါ။
သတိလေးတစ်ချက်
id ကို Date.now() နဲ့ generate လုပ်တာ project practice အတွက်တော့ လုံလောက်ပေမယ့် production app မှာတော့ uuid library လိုမျိုး ပိုတိကျတဲ့ id generator သုံးသင့်ပါတယ်။