การแปลง HTML เป็น JSX คืออะไร?
การแปลง HTML เป็น JSX คือกระบวนการเปลี่ยน HTML markup มาตรฐานให้เป็น syntax ของ JSX ที่ React component สามารถแสดงผลได้ JSX มีลักษณะคล้าย HTML แต่ปฏิบัติตามข้อกำหนดการตั้งชื่อและกฎของ JavaScript แอตทริบิวต์อย่าง class จะกลายเป็น className, for จะกลายเป็น htmlFor และ style string แบบ inline จะถูกแทนที่ด้วย JavaScript object การเปลี่ยนแปลงเหล่านี้เป็นสิ่งจำเป็นเนื่องจาก JSX คอมไพล์เป็น React.createElement() call ซึ่งชื่อแอตทริบิวต์ต้องตรงกับชื่อ property ของ DOM API ไม่ใช่ชื่อแอตทริบิวต์ HTML
การแมประหว่างแอตทริบิวต์ HTML และ JSX prop ถูกกำหนดโดยเอกสาร DOM element ของ React React ใช้ camelCase สำหรับแอตทริบิวต์หลายคำ (tabindex กลายเป็น tabIndex, maxlength กลายเป็น maxLength) เพราะ JavaScript identifier ไม่สามารถมีขีดกลางได้ แท็กที่ปิดตัวเองอย่าง <img>, <br> และ <input> ต้องมี slash ต่อท้ายใน JSX (<img />) เนื่องจาก JSX ปฏิบัติตามกฎ XML ซึ่งทุกแท็กต้องปิดอย่างชัดเจน
htmlToJsxContent.whatBody3
ทำไมต้องใช้ตัวแปลง HTML เป็น JSX?
การเปลี่ยนชื่อแอตทริบิวต์และเขียน style string ใหม่ทีละองค์ประกอบใน HTML หลายสิบรายการนั้นช้าและเสี่ยงต่อความผิดพลาด ตัวแปลงจัดการการเปลี่ยนแปลงทั้งหมดพร้อมกัน ให้คุณวาง HTML จากแหล่งใดก็ได้และรับ JSX ที่ถูกต้องภายในไม่กี่วินาที
กรณีการใช้งานตัวแปลง HTML เป็น JSX
ตารางอ้างอิงการแมปแอตทริบิวต์ HTML เป็น JSX
ตารางด้านล่างแสดงแอตทริบิวต์ HTML ที่เปลี่ยนแปลงเมื่อแปลงเป็น JSX แอตทริบิวต์ที่ไม่ได้ระบุในตาราง (id, src, href, alt, placeholder ฯลฯ) จะไม่เปลี่ยนแปลง เนื่องจากชื่อ HTML ตรงกับชื่อ property ของ DOM API อยู่แล้ว
| แอตทริบิวต์ HTML | JSX Prop | หมายเหตุ |
|---|---|---|
| class | className | Reserved word in JavaScript |
| for | htmlFor | Reserved word in JavaScript |
| tabindex | tabIndex | camelCase convention |
| readonly | readOnly | camelCase convention |
| maxlength | maxLength | camelCase convention |
| minlength | minLength | camelCase convention |
| cellpadding | cellPadding | camelCase convention |
| cellspacing | cellSpacing | camelCase convention |
| rowspan | rowSpan | camelCase convention |
| colspan | colSpan | camelCase convention |
| enctype | encType | camelCase convention |
| autocomplete | autoComplete | camelCase convention |
| autofocus | autoFocus | camelCase convention |
| autoplay | autoPlay | camelCase convention |
| contenteditable | contentEditable | camelCase convention |
| crossorigin | crossOrigin | camelCase convention |
| novalidate | noValidate | camelCase convention |
| allowfullscreen | allowFullScreen | camelCase convention |
| spellcheck | spellCheck | camelCase convention |
| http-equiv | httpEquiv | Hyphen removed, camelCase |
| onclick | onClick | Event handler camelCase |
| onchange | onChange | Event handler camelCase |
| onsubmit | onSubmit | Event handler camelCase |
การแปลง Inline Style: HTML กับ JSX
Inline style เป็นส่วนที่เสี่ยงต่อความผิดพลาดมากที่สุดในการแปลง HTML เป็น JSX เพราะทั้งรูปแบบค่าและชื่อ property ล้วนเปลี่ยนแปลง:
<div style="background-color: #fff; font-size: 14px; margin-top: 10px;">
<div style={{
backgroundColor: '#fff',
fontSize: '14px',
marginTop: 10
}}>ตัวอย่างโค้ด
ตัวอย่างเหล่านี้แสดงวิธีแปลง HTML เป็น JSX โดยอัตโนมัติในภาษาและสภาพแวดล้อมต่างๆ แต่ละตัวอย่างครอบคลุมการเปลี่ยนชื่อแอตทริบิวต์ การแปลง style และการจัดการ self-closing tag
// Simple attribute conversion using string replacement
function htmlToJsx(html) {
return html
.replace(/\bclass=/g, 'className=')
.replace(/\bfor=/g, 'htmlFor=')
.replace(/\btabindex=/g, 'tabIndex=')
.replace(/<!--([\s\S]*?)-->/g, '{/*$1*/}')
}
htmlToJsx('<div class="box" tabindex="0"><!-- note --></div>')
// → '<div className="box" tabIndex="0">{/* note */}</div>'import parse from 'html-react-parser'
// Parse HTML string into React elements (handles all JSX rules)
const element = parse('<div class="card"><img src="photo.jpg" alt="Photo"></div>')
// Returns: React.createElement('div', { className: 'card' },
// React.createElement('img', { src: 'photo.jpg', alt: 'Photo' }))
// With custom element replacement
const options = {
replace(domNode) {
if (domNode.name === 'img') {
return <OptimizedImage src={domNode.attribs.src} alt={domNode.attribs.alt} />
}
}
}
const custom = parse('<img src="photo.jpg" alt="Photo">', options)from bs4 import BeautifulSoup
import re
ATTR_MAP = {
'class': 'className', 'for': 'htmlFor',
'tabindex': 'tabIndex', 'readonly': 'readOnly',
'maxlength': 'maxLength', 'autocomplete': 'autoComplete',
}
def html_to_jsx(html: str) -> str:
"""Convert HTML attribute names to JSX equivalents."""
for html_attr, jsx_attr in ATTR_MAP.items():
html = re.sub(rf'\b{html_attr}=', f'{jsx_attr}=', html)
# Convert HTML comments to JSX comments
html = re.sub(r'<!--(.*?)-->', r'{/*\1*/}', html)
return html
print(html_to_jsx('<label for="email" class="field">Email</label>'))
# → '<label htmlFor="email" className="field">Email</label>'package main
import (
"fmt"
"strings"
)
var attrMap = map[string]string{
"class=": "className=",
"for=": "htmlFor=",
"tabindex=": "tabIndex=",
"readonly": "readOnly",
}
func htmlToJSX(html string) string {
result := html
for old, new := range attrMap {
result = strings.ReplaceAll(result, old, new)
}
// Convert comments
result = strings.ReplaceAll(result, "<!--", "{/*")
result = strings.ReplaceAll(result, "-->", "*/}")
return result
}
func main() {
html := `<div class="wrapper"><input readonly tabindex="1"></div>`
fmt.Println(htmlToJSX(html))
// → <div className="wrapper"><input readOnly tabIndex="1"></div>
}