JSX & Elements
JSX เป็นแค่ syntax
หัวข้อที่มีชื่อว่า “JSX เป็นแค่ syntax”JSX หน้าตาเหมือน HTML แต่เป็น syntax sugar ของการเรียกฟังก์ชัน JavaScript ธรรมดา อันนี้:
const el = <button className="primary">Click</button>;compile (ผ่าน JSX transform สมัยใหม่) เป็นประมาณนี้:
import { jsx as _jsx } from "react/jsx-runtime";const el = _jsx("button", { className: "primary", children: "Click" });ผลที่สำคัญ: JSX เป็น expression ที่ประเมินค่าเป็นค่าที่คุณเก็บใส่ตัวแปรได้ return จากฟังก์ชันได้ ใส่ใน array ได้ หรือส่งเป็น prop ได้ ไม่ใช่ template language ที่มีกฎของตัวเอง — JSX คือ JavaScript ดังนั้น { } ใน JSX ก็แค่หลุดกลับไปเป็น JS expression
function List({ items, showHeader }) { return ( <ul> {showHeader && <li className="header">Items</li>} {/* JS expression */} {items.map((item) => ( <li key={item.id}>{item.text}</li> {/* JS expression */} ))} </ul> );}element คือ object ธรรมดา
หัวข้อที่มีชื่อว่า “element คือ object ธรรมดา”_jsx("button", ...) return อะไรจริง ๆ? ไม่ใช่ DOM node — แต่เป็น object JavaScript ธรรมดา ที่อธิบายสิ่งที่คุณต้องการ:
// Roughly what a React element is:const el = { type: "button", // a string for host elements, or a function for components props: { className: "primary", children: "Click" }, key: null, // ...internal fields};นี่คือ insight สำคัญ: React element คือคำอธิบายที่ถูกและ immutable — ไม่ใช่ตัวจริง สร้าง element พันตัวก็แค่สร้าง object เล็ก ๆ พันตัว React สร้าง tree ของคำอธิบายเหล่านี้ทุกครั้งที่ render แล้วเทียบกับ tree ก่อนหน้าเพื่อตัดสินว่าจะแตะ DOM จริงตรงไหน (นั่นคือ reconciliation บทเรียนถัดไป)
flowchart LR
jsx["JSX
<button>Click</button>"] -->|compiler| call["jsx('button', props)"]
call --> obj["element object
{ type, props, key }"]
obj --> tree["tree of elements
(the description)"]
tree -->|React| dom["real DOM
(the result)"] component เทียบกับ host element
หัวข้อที่มีชื่อว่า “component เทียบกับ host element”field type บอก React ว่าเป็น node ชนิดไหน:
typeที่เป็น string ("button","div") คือ host element — React รู้วิธีแปลงเป็น DOM node จริงtypeที่เป็น function (Counter,Greeting) คือ component — React เรียกฟังก์ชันนั้นเพื่อได้ element เพิ่ม วนซ้ำไปเรื่อย ๆ จนเหลือแต่ host element
<Counter />// element: { type: Counter (the function), props: {} }// React calls Counter() → gets more elements → repeats until only host elements remainนี่คือเหตุผลที่ชื่อ component ต้องขึ้นต้นด้วยตัวใหญ่ ใน JSX: <Counter /> (ตัวใหญ่) แปลว่า “เรียก component Counter” ส่วน <counter /> (ตัวเล็ก) แปลว่า “สร้าง host element ชื่อ counter ตรง ๆ” ตัวเล็กตัวใหญ่คือวิธีที่ compiler ตัดสินระหว่าง type ที่เป็น string กับการอ้างถึงตัวแปร