JSX: ส่วนขยายของ JavaScript และตัวอย่างการใช้งาน

ผู้แต่ง: IT Sectr เผยแพร่เมื่อ: 2026-07-03 เวลาอ่าน: 10 นาที

JSX คือส่วนขยายไวยากรณ์ของ JavaScript ที่มีลักษณะคล้าย XML พัฒนาโดยทีม React เพื่ออธิบายส่วนติดต่อผู้ใช้แบบเชิงประกาศ (declarative) ต่างจากเทมเพลตเอนจิน JSX จะถูกคอมไพล์เป็นการเรียกฟังก์ชัน JavaScript ทั่วไป ซึ่งให้พลังเต็มรูปแบบของภาษาในการเขียนมาร์กอัป จากข้อมูลของ React, 2024 JSX ถูกสนับสนุนในเฟรมเวิร์กและไลบรารี React สมัยใหม่ทั้งหมด

สิ่งสำคัญ

  • JSX คือน้ำตาลเชิงไวยากรณ์ (syntactic sugar) ที่อยู่เหนือ React.createElement ซึ่งช่วยให้เขียนมาร์กอัปที่คล้าย HTML ใน JavaScript ได้
  • นิพจน์ ใน JSX ถูกแทรกด้วยเครื่องหมายปีกกา — ใช้ JavaScript expression ใด ๆ ก็ได้
  • แอตทริบิวต์ ใน JSX เขียนแบบ camelCase (className, onClick, tabIndex) ไม่ใช่ kebab-case
  • การแปลง JSX เป็น JS ทำโดย Babel, TypeScript หรือ esbuild ก่อนทำงานในเบราว์เซอร์
  • การป้องกัน XSS มีในตัว — React หลีกเลี่ยง (escape) ค่าทั้งหมดก่อนเรนเดอร์เพื่อป้องกันการฉีด (injection)

JSX คืออะไร?

JSX (JavaScript XML) คือส่วนขยายไวยากรณ์ของ JavaScript ถูกนำเสนอครั้งแรกใน React ในปี 2013 มันช่วยให้นักพัฒนาอธิบายโครงสร้างของส่วนติดต่อผู้ใช้ในรูปแบบเชิงประกาศ โดยผสมผสานมาร์กอัปและตรรกะไว้ในไฟล์เดียว

ก่อนที่ JSX จะเกิดขึ้น นักพัฒนาใช้ เทมเพลตสตริง (Mustache, Handlebars) หรือสร้าง DOM element ด้วยตนเองผ่าน document.createElement ทั้งสองแนวทางมีข้อเสีย: เทมเพลตสตริงไม่มีการตรวจสอบชนิด และการสร้าง DOM ด้วยมือยุ่งยากและเกิดข้อผิดพลาดได้ง่าย

React เลือกเส้นทางที่ต่างออกไป — การฝังมาร์กอัปลงในโค้ดโดยตรง การตัดสินใจนี้ทำให้เกิดการถกเถียงในชุมชน แต่เมื่อเวลาผ่านไปก็กลายเป็นมาตรฐาน ทุกวันนี้ JSX ถูกใช้ไม่เพียงใน React แต่ยังใช้ใน SolidJS, Preact, Qwik และแม้แต่ใน Vue ผ่านปลั๊กอิน

ไวยากรณ์พื้นฐานของ JSX

JSX element มีลักษณะเหมือน HTML tag แต่ถูกฝังใน JavaScript โดยตรง แต่ละ element ถูกแปลงเป็นการเรียก React.createElement ด้วยอาร์กิวเมนต์สามตัว: ชนิดของ element, ออบเจกต์ของ props และ child element หนึ่ง root element เป็นกฎบังคับ: JSX expression ต้องคืนค่า parent element หนึ่งตัวหรือ fragment

js
import React from 'react';

// JSX พื้นฐาน - องค์ประกอบรากเดียว
const element = (
  <div className="app">
    <h1>Hello, World!</h1>
    <p>Welcome to React</p>
  </div>
);

Fragment สำหรับการจัดกลุ่ม

เมื่อไม่ต้องการ DOM node ที่เกินจำเป็น ให้ใช้ React.Fragment หรือไวยากรณ์แบบสั้น <></> Fragment ไม่สร้าง DOM element จริง แต่เพียงจัดกลุ่ม child nodes ซึ่งมีประโยชน์โดยเฉพาะในตารางและรายการที่ wrapper ที่เกินจำเป็นจะทำให้โครงสร้าง HTML เสียหาย

js
function Columns() {
  return (
    <>
      <td>First</td>
      <td>Second</td>
    </>
  );
}

นิพจน์และตัวแปรใน JSX

JavaScript expression ใด ๆ ถูกแทรกลงใน JSX ด้วยเครื่องหมายปีกกา { } ภายในสามารถใช้ตัวแปร การเรียกฟังก์ชัน ตัวดำเนินการ ternary และเมธอดของอาร์เรย์ การเรนเดอร์แบบมีเงื่อนไข ทำได้ด้วยตัวดำเนินการ ternary หรือ logical AND

js
function Greeting({ name, isLoggedIn }) {
  const items = ['Red', 'Green', 'Blue'];

  return (
    <div>
      {/* Expression with variable */}
      <h1>Hello, {name}</h1>

      {/* Conditional rendering */}
      {isLoggedIn ?
        <p>Welcome back!</p :
        <button>Login</button>
      }

      {/* Render array */}
      <ul>
        {items.map(item =>
          <li key={item}>{item}</li>
        )}
      </ul>
    </div>
  );
}

ข้อจำกัดสำคัญคือ ภายในเครื่องหมายปีกกาสามารถใช้ได้เฉพาะ นิพจน์ ไม่ใช่คำสั่ง (statement) ไม่สามารถใช้ if/else, for, switch ได้ — ใช้ได้เฉพาะตัวดำเนินการ ternary ตัวดำเนินการทางตรรกะ และเมธอดของอาร์เรย์ การเรียกฟังก์ชันทำได้ รวมถึง arrow function

ความแตกต่างระหว่าง JSX และ HTML

JSX ดูคล้าย HTML แต่มีความแตกต่างโดยพื้นฐาน แอตทริบิวต์ เขียนแบบ camelCase — className แทน class, onClick แทน onclick, tabIndex แทน tabindex เนื่องจาก JSX ถูกแปลงเป็น JavaScript ซึ่งไม่อนุญาตให้ใช้เครื่องหมายยัติภังค์ (hyphen) ในชื่อคุณสมบัติ

HTMLJSXสาเหตุ
class="wrapper"className="wrapper"class เป็นคำสงวนใน JS
onclick="handle()"onClick={handle}camelCase สำหรับคุณสมบัติ JS
style="color: red"style={{ color: 'red' }}ออบเจกต์สไตล์แทนสตริง
<input disabled><input disabled={true}>ระบุ boolean attribute อย่างชัดเจน

อีกหนึ่งความแตกต่างที่สำคัญคือ self-closing tag ใน HTML บางแท็ก (br, hr, input) ไม่จำเป็นต้องปิด ใน JSX แท็กที่ self-closing ทั้งหมดต้องมีเครื่องหมาย slash ปิด: <br />, <input /> ชื่อของ SVG attribute ก็ถูกแปลงเป็น camelCase เช่นกัน: strokeWidth, fillOpacity

JSX ถูกแปลงเป็น JavaScript อย่างไร

เบราว์เซอร์ไม่เข้าใจ JSX โดยตรง ก่อนทำงาน JSX code ต้องผ่าน transpiler — Babel, TypeScript หรือ esbuild แต่ละ JSX element ถูกแปลงเป็นการเรียก createElement หรือ jsx/runtime

การแปลงผ่าน Babel

js
// JSX ต้นฉบับ
const element = <h1 className="title">Hello</h1>;

// หลังการแปลง
const element = React.createElement(
  'h1',
  { className: 'title' },
  'Hello'
);

ตั้งแต่ React 17 มีการแปลง JSX แบบใหม่ที่ไม่ต้อง import React การ import แบบอัตโนมัติ ของ jsx-runtime ช่วยให้เขียน component ได้โดยไม่ต้องใช้ import React from 'react' Babel และ TypeScript สนับสนุนการแปลงนี้ผ่านการตั้งค่า {"runtime": "automatic"}

JSX นอกเหนือจาก React: Solid, Preact, Vue

แม้ JSX จะถูกเชื่อมโยงกับ React แต่เฟรมเวิร์กอื่น ๆ ก็ใช้มันเช่นกัน SolidJS ใช้ JSX พร้อมการคอมไพล์เป็น DOM node จริง โดยไม่มี Virtual DOM Preact เป็นทางเลือกที่เบากว่า React ที่สนับสนุน JSX อย่างเต็มที่ Vue สนับสนุน JSX ผ่าน @vue/babel-plugin-jsx แม้ template จะเป็นรูปแบบหลักของมัน

ความแตกต่างที่สำคัญคือ semantics ของนิพจน์ ใน React JSX expression จะถูกทำงานทุกครั้งที่เรนเดอร์ ใน SolidJS JSX ถูกคอมไพล์เพียงครั้งเดียว และการอัปเดตถูกติดตามผ่านสัญญาณ (signals) สิ่งนี้ส่งผลต่อประสิทธิภาพ: SolidJS ไม่ต้องใช้ Virtual DOM และ reconciliation ดังนั้นการเรนเดอร์ JSX จึงเร็วกว่า

ใน TypeScript JSX ถูกรองรับในระดับภาษา ไฟล์ที่มีนามสกุล .tsx จัดการไวยากรณ์ JSX โดยอัตโนมัติ การกำหนดชนิดของ props เป็นหนึ่งในข้อได้เปรียบหลักของ TypeScript + JSX: IDE แนะนำแอตทริบิวต์ที่คาดหวัง ชนิดของ callback และความจำเป็นของ props

แนวปฏิบัติที่ดีที่สุดสำหรับ JSX

เขียน JSX code ที่อ่านง่ายและดูแลรักษาง่าย ดึงนิพจน์ที่ซับซ้อนออกไป ใส่ตัวแปรหรือฟังก์ชันแยก — ช่วยให้อ่านง่ายขึ้นและทดสอบตรรกะแยกจากมาร์กอัปได้ ใช้ fragment แทนการห่อ div ที่เกินจำเป็น

กฎการจัดตาราง (tab) — รักษาระดับการเยื้อง (indent) สำหรับ element ที่ซ้อนกัน แต่ละระดับการซ้อนคือหนึ่งระดับการเยื้อง แท็กปิดต้องอยู่ในระดับเดียวกับแท็กเปิด สำหรับแอตทริบิวต์ที่ยาวให้ใช้การขึ้นบรรทัดใหม่

หลีกเลี่ยง inline arrow function ใน props ถ้ามันถูกสร้างขึ้นทุกครั้งที่เรนเดอร์ ในกรณีเช่นนี้ให้ห่อ callback ด้วย useCallback หรือย้ายฟังก์ชันออกไปนอก component แบ่ง component ที่ซับซ้อนเป็นส่วนย่อย ๆ — แต่ละ component ควรรับผิดชอบหนึ่งหน่วยตรรกะของอินเทอร์เฟซ

คำถามที่พบบ่อย

ใช้ JSX โดยไม่ใช้ React ได้ไหม?

ได้ ผ่าน Babel-ปลั๊กอิน @babel/plugin-transform-react-jsx คุณสามารถตั้งค่า JSX สำหรับไลบรารีใดก็ได้ SolidJS, Preact, Nerv และเฟรมเวิร์กอื่น ๆ ใช้ JSX พร้อม runtime ของตัวเอง สำหรับความเป็นอิสระโดยสมบูรณ์คุณสามารถระบุ pragma เป็นฟังก์ชันของคุณเองได้

ทำไมใน JSX ถึงใช้ class แทน className ไม่ได้?

class เป็นคำสงวนใน JavaScript JSX ถูกแปลงเป็น createElement ซึ่งอาร์กิวเมนต์ที่สองคือออบเจกต์ของ props คุณสมบัติ class ขัดแย้งกับไวยากรณ์ class ของ ES6 ดังนั้น React จึงเลือก className

จะเพิ่มหลายคลาสใน JSX ได้อย่างไร?

ใช้ เทมเพลตสตริง หรือไลบรารี classnames: className={`"btn ${isActive ? 'active' : ''}"`} สำหรับตรรกะที่ซับซ้อนให้ติดตั้ง npm package clsx หรือ classnames ซึ่งรับออบเจกต์และอาร์เรย์

JSX รองรับโครงสร้างแบบมีเงื่อนไขหรือไม่?

JSX รองรับเฉพาะ นิพจน์ ไม่ใช่คำสั่ง สำหรับเงื่อนไขให้ใช้ตัวดำเนินการ ternary, logical AND (&&) หรือ logical OR (||) สำหรับตรรกะที่ซับซ้อนให้แยกเงื่อนไขออกไปใส่ตัวแปรหรือฟังก์ชัน

ทำไมใน JSX ถึงต้องมี key สำหรับรายการ?

แอตทริบิวต์ key ช่วยให้ React ระบุ element ของรายการเมื่อเรนเดอร์ซ้ำ หากไม่มี key React จะวาดรายการใหม่ทั้งหมดเมื่อมีการเปลี่ยนแปลง ด้วย key ที่ไม่ซ้ำกัน React จะนำ DOM node กลับมาใช้ใหม่และจัดลำดับ element แทนที่จะสร้างใหม่

สรุป

  • JSX คือส่วนขยายของ JavaScript ที่คล้าย XML สำหรับอธิบาย UI แบบเชิงประกาศ เป็นทางเลือกแทนเทมเพลตสตริง
  • เครื่องหมายปีกกา ช่วยให้ฝัง JavaScript expression ใด ๆ ได้ — ตัวแปร ฟังก์ชัน ตัวดำเนินการ ternary
  • แอตทริบิวต์ ใน JSX เขียนแบบ camelCase สไตล์ส่งผ่านเป็นออบเจกต์ boolean attribute ระบุอย่างชัดเจน
  • การแปลง JSX เป็น createElement ทำโดย Babel หรือ TypeScript โดยอัตโนมัติ
  • ต้องมี root element หนึ่งตัว หรือ fragment สำหรับทุก JSX expression
  • JSX นอกเหนือจาก React — SolidJS, Preact, Vue และ Qwik สนับสนุน JSX ผ่าน runtime ของตัวเองเช่นกัน
  • TypeScript ที่มีนามสกุล .tsx ให้การกำหนดชนิด props และแอตทริบิวต์ JSX อย่างสมบูรณ์

เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร

IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ

ปรึกษาโครงการ

อ่านเพิ่มเติม