ตัวอย่างที่ลงมือทำจริง: ฟีเจอร์ "รายการโปรด"
มาสร้างฟีเจอร์เล็ก ๆ กันตั้งแต่ต้นจนจบ: ผู้ใช้สามารถทำเครื่องหมายรายการในลิสต์ว่าเป็นรายการโปรด และเห็นจำนวนของรายการที่พวกเขาถูกใจแล้ว
การตัดเป็นชิ้น (Slicing)
นี่คือวิธีที่ผมจะตัดมันออกเป็นขั้นตอนแนวตั้ง:
- เพิ่มปุ่มดาวข้างรายการแต่ละอัน (ยังไม่ทำอะไร แค่ปรากฏขึ้นมา)
- คลิกดาวเพื่อสลับรูปลักษณ์เปิด/ปิด (แค่ state เฉย ๆ ยังไม่บันทึก)
- แสดงตัวนับ "★ 3 favorites" ที่สะท้อนการสลับเหล่านั้น
- บันทึกรายการโปรดให้คงอยู่แม้โหลดหน้าใหม่
สังเกตว่าแต่ละขั้นตอนรันได้และมองเห็นได้อย่างอิสระ คุณสามารถหยุดหลังจากขั้นตอนใดขั้นตอนหนึ่งก็ได้ แล้วยังมีแอปที่ใช้งานได้อยู่
ขั้นตอนที่ 1: ปุ่ม
พรอมป์ที่ดีจะระบุชื่อไฟล์ การเปลี่ยนแปลง และสิ่งที่ ห้าม แตะ:
In the ItemCard component (src/components/ItemCard.jsx), add a star
button in the top-right corner of each card. It should render an
outline star icon. Don't wire up any click behavior yet — just make
it appear. Keep the rest of the card layout unchanged.
รันแอป เห็นดาวไหม? ดี คอมมิตเลย:
git add -A && git commit -m "Add star button to item cards"
ขั้นตอนที่ 2: สลับ state
Make the star button toggle between filled and outline when clicked.
Track this with local component state — don't save it anywhere yet.
A filled star means favorited.
ลองคิดว่า state คือความจำระยะสั้นของแอป — สิ่งที่เป็นจริง ณ ตอนนี้ เช่น ดาวดวงหนึ่งกำลังถูกเติมสีอยู่หรือไม่ ตอนนี้คุณกำลังจัดการ state และ UI ไปพร้อมกัน ซึ่งเป็นเรื่องปกติ (UI หรือ user interface คือแค่ส่วนของแอปที่คนมองเห็นและคลิกได้) AI น่าจะเพิ่มโค้ดประมาณนี้:
const [isFavorite, setIsFavorite] = useState(false);
<button onClick={() => setIsFavorite(!isFavorite)}>
{isFavorite ? <StarFilled /> : <StarOutline />}
</button>
คลิกดาวสักสองสามดวง มันสลับไหม? คอมมิต
ขั้นตอนที่ 3: ตัวนับ
Add a "★ N favorites" counter at the top of the item list. It should
count how many items currently have their star filled. Lift the
favorite state up to the list component if you need to so the counter
can see it.
ขั้นตอนนี้อาจต้องให้ AI จัดโครงสร้างใหม่ว่า state อยู่ตรงไหน — นั่นเป็นเรื่องที่คาดไว้แล้ว และนี่แหละคือเหตุผลที่คุณทำมันเป็นขั้นตอนเล็ก ๆ แยกต่างหาก รันมัน สลับดาวสักสองสามดวง ดูตัวเลขเปลี่ยน คอมมิต
ขั้นตอนที่ 4: ทำให้คงอยู่ (persist)
Persist favorites so they survive a page reload. Use localStorage for
now — save the list of favorited item IDs whenever it changes, and
load it on startup.
(localStorage เป็นแค่สมุดบันทึกเล็ก ๆ ที่เบราว์เซอร์เก็บไว้บนคอมพิวเตอร์ของผู้เยี่ยมชมเอง เพื่อให้แอปจดข้อมูลไว้แล้วหามันเจออีกครั้งหลังโหลดหน้าใหม่) โหลดหน้าใหม่ ยังเป็นรายการโปรดอยู่ไหม? คุณเพิ่งส่งฟีเจอร์ออกไปแล้ว ทีละ slice ที่รันได้จริง
นี่คือวิธีที่ชิ้นส่วนต่าง ๆ ของฟีเจอร์ที่เสร็จสมบูรณ์แล้วสื่อสารกัน การคลิกไหลลงไปสู่ state หน้าจอวาดใหม่จาก state และ state ถูกสะท้อนไปยัง storage เพื่อให้มันอยู่รอดหลังโหลดหน้าใหม่:
┌─────────────────────────────────────────────┐
│ │
click star redraws from
│ (event) state
▼ ▲
┌────────┐ updates ┌─────────┐ feeds ┌────────┐
│ UI │─────────────▶│ STATE │───────────▶│ UI │
│(button)│ │(in app │ │(filled │
└────────┘ │ memory) │ │ star + │
└────┬────┘ │counter)│
│ save on change └────────┘
▼
┌──────────┐
│ STORAGE │ ◀── load on startup,
│(localSt.)│ so it survives reload
└──────────┘