ข้ามไปยังเนื้อหา

JSX & Elements

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>
);
}

_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)"]
จาก JSX สู่ element สู่ DOM

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 กับการอ้างถึงตัวแปร

JSX compile เป็นอะไร?
React element คืออะไร?
ทำไม component ต้องขึ้นต้นด้วยตัวใหญ่ใน JSX (`<Counter />` ไม่ใช่ `<counter />`)?
`{ }` ใน JSX คืออะไร?