什么是 HTML 转 JSX 转换?
HTML 转 JSX 转换是将标准 HTML 标记转化为 JSX 语法的过程,使 React 组件能够正常渲染。JSX 外观与 HTML 相似,但遵循 JavaScript 的命名规范和规则。class 属性变为 className,for 变为 htmlFor,行内 style 字符串替换为 JavaScript 对象。这些变更是必要的,因为 JSX 最终会编译为 React.createElement() 调用,其中属性名必须与 DOM API 属性名匹配,而非 HTML 属性名。
HTML 属性与 JSX props 之间的映射关系由 React 的 DOM 元素文档定义。React 对多个单词组成的属性使用驼峰命名法(tabindex 变为 tabIndex,maxlength 变为 maxLength),因为 JavaScript 标识符不能包含连字符。像 <img>、<br> 和 <input> 这样的自闭合标签在 JSX 中必须包含结尾斜杠(<img />),因为 JSX 遵循 XML 规则,每个标签都必须显式闭合。
除属性重命名外,HTML 转 JSX 转换还会处理行内样式和注释。HTML style 属性使用 CSS 字符串语法(style="color: red; font-size: 14px"),而 JSX 期望使用驼峰命名属性的 JavaScript 对象(style={{ color: 'red', fontSize: '14px' }})。HTML 注释(<!-- -->)变为 JSX 表达式注释({/* */})。遗漏任何一项转换都会在 React 应用中产生运行时错误或无声的渲染缺陷。
为什么使用 HTML 转 JSX 转换器?
在数十个 HTML 元素中手动重命名属性、重写 style 字符串既耗时又容易出错。转换器一次性处理所有转换,让你粘贴任意来源的 HTML,在数秒内获得有效的 JSX。
HTML 转 JSX 使用场景
HTML 转 JSX 属性映射参考
下表列出了转换为 JSX 时需要更改的 HTML 属性。未列出的属性(id、src、href、alt、placeholder 等)保持不变,因为它们的 HTML 名称已与对应的 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 |
行内样式转换:HTML 与 JSX 的对比
行内样式是 HTML 转 JSX 转换中最容易出错的部分,因为值的格式和属性名都会发生变化:
<div style="background-color: #fff; font-size: 14px; margin-top: 10px;">
<div style={{
backgroundColor: '#fff',
fontSize: '14px',
marginTop: 10
}}>代码示例
以下示例展示如何在不同语言和环境中通过编程方式将 HTML 转换为 JSX,涵盖属性重命名、样式转换和自闭合标签处理。
// 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>
}