ToolDeck

HTML to JSX

将 HTML 转换为 React JSX — class→className,style 字符串→对象

加载示例

HTML Input

JSX Output

本地运行 · 粘贴密钥安全无忧
JSX 输出将显示在此处…

什么是 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 输出。转换器在一次处理中完成 class、for、style、事件处理器、布尔属性和自闭合标签的全部转换。
🔒
本地隐私处理
所有转换在浏览器本地完成。你的 HTML 不会离开页面,因此可以安全地转换包含内部代码、API 端点或敏感内容的标记。
📋
无需账号或配置
打开页面即可开始转换。无需登录,无需安装 npm 包,无需配置构建步骤。在任何支持现代浏览器的设备上均可使用。
🔧
完整属性覆盖
转换所有标准 HTML 到 JSX 的属性映射,包括 className、htmlFor、tabIndex、readOnly、autoComplete 及 20 余个其他属性。同时处理 onclick 到 onClick 等事件处理器的重命名。

HTML 转 JSX 使用场景

前端开发者:迁移模板
将现有 HTML 页面或组件迁移到 React 项目时,将标记粘贴到转换器中,而无需在数百行代码中手动查找 class 和 for 属性。
后端工程师:嵌入 HTML 邮件
邮件模板以纯 HTML 编写。在 React 管理后台或预览组件中渲染时,将 HTML 转换为有效的 JSX,以避免 className 和 style 语法错误。
运维工程师:转换监控看板组件
监控看板通常使用 HTML 片段来实现自定义组件。在将它们集成到基于 React 的内部工具平台(如 Retool 或自定义管理面板)时,将这些片段转换为 JSX。
QA 工程师:复现 Bug 报告
当 Bug 报告包含原始 HTML 输出时,将其转换为 JSX,以便在 React 测试环境或 Storybook story 中快速渲染,进行可视化检查和调试。
设计师:基于 HTML 原型进行设计
Figma 等设计工具可以导出 HTML/CSS。将导出的标记转换为 JSX,直接放入 React 原型中,无需手动清理属性。
学生:学习 React 语法
并排对比 HTML 输入与 JSX 输出,理解哪些属性发生了变化及其原因。通过观察转换过程,比单纯阅读文档更容易记住 React 的命名规范。

HTML 转 JSX 属性映射参考

下表列出了转换为 JSX 时需要更改的 HTML 属性。未列出的属性(id、src、href、alt、placeholder 等)保持不变,因为它们的 HTML 名称已与对应的 DOM API 属性名匹配。

HTML 属性JSX Prop说明
classclassNameReserved word in JavaScript
forhtmlForReserved word in JavaScript
tabindextabIndexcamelCase convention
readonlyreadOnlycamelCase convention
maxlengthmaxLengthcamelCase convention
minlengthminLengthcamelCase convention
cellpaddingcellPaddingcamelCase convention
cellspacingcellSpacingcamelCase convention
rowspanrowSpancamelCase convention
colspancolSpancamelCase convention
enctypeencTypecamelCase convention
autocompleteautoCompletecamelCase convention
autofocusautoFocuscamelCase convention
autoplayautoPlaycamelCase convention
contenteditablecontentEditablecamelCase convention
crossorigincrossOrigincamelCase convention
novalidatenoValidatecamelCase convention
allowfullscreenallowFullScreencamelCase convention
spellcheckspellCheckcamelCase convention
http-equivhttpEquivHyphen removed, camelCase
onclickonClickEvent handler camelCase
onchangeonChangeEvent handler camelCase
onsubmitonSubmitEvent handler camelCase

行内样式转换:HTML 与 JSX 的对比

行内样式是 HTML 转 JSX 转换中最容易出错的部分,因为值的格式和属性名都会发生变化:

HTML style 属性
由分号分隔的 CSS 声明字符串。属性名使用 kebab-case(background-color、font-size、border-radius)。值始终为字符串,包括带单位的数值。
<div style="background-color: #fff;
  font-size: 14px;
  margin-top: 10px;">
JSX style prop
使用驼峰命名属性的 JavaScript 对象(backgroundColor、fontSize、borderRadius)。字符串值需加引号。无单位的数值属性(lineHeight、opacity、zIndex、flexGrow)可以直接使用数字。
<div style={{
  backgroundColor: '#fff',
  fontSize: '14px',
  marginTop: 10
}}>

代码示例

以下示例展示如何在不同语言和环境中通过编程方式将 HTML 转换为 JSX,涵盖属性重命名、样式转换和自闭合标签处理。

JavaScript (DOM API)
// 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>'
JavaScript (html-react-parser)
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)
Python (BeautifulSoup)
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>'
Go
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>
}

常见问题

HTML 和 JSX 有什么区别?
JSX 是 React 使用的 JavaScript 语法扩展,外观类似 HTML,但会编译为 React.createElement() 调用。主要区别包括:class 变为 className,for 变为 htmlFor,行内样式使用 JavaScript 对象而非 CSS 字符串,所有标签必须显式闭合(包括 <img /> 等空元素)。JSX 还允许在花括号内嵌入 JavaScript 表达式。
React 为什么使用 className 而不是 class?
class 是 JavaScript 的保留关键字。由于 JSX 会编译为 JavaScript 函数调用,将 class 用作 prop 名会导致语法错误。React 选择了 className,因为它与 JavaScript 已用于读取和设置 DOM 元素 CSS 类的 DOM API 属性名(element.className)一致。
我需要手动将 HTML 转换为 JSX 吗?
不需要。你可以使用本工具等在线转换器,或通过 htmltojsx(npm)、html-react-parser 等库自动完成转换。对于大规模迁移,codemod 或 jscodeshift 等工具可以转换整个代码库。手动转换只适用于少量代码片段。
JSX 中如何处理行内样式?
在 JSX 中,style 属性接受 JavaScript 对象而非 CSS 字符串。属性名使用驼峰命名(backgroundColor 而非 background-color)。值默认为字符串,但 lineHeight、opacity、zIndex 等特定数值属性可以直接使用不带单位的数字。style={{ color: 'red' }} 中的双层花括号并非特殊语法:外层花括号是 JSX 表达式,内层花括号是 JavaScript 对象字面量。
JSX 中可以使用 HTML 注释吗?
不能。HTML 注释(<!-- comment -->)在 JSX 中无效。应使用包裹在花括号中的 JavaScript 块注释:{/* comment */}。本转换器会自动处理此转换。JSX 注释必须位于父元素内部,不能在组件 return 的顶层使用。
哪些 HTML 属性在 JSX 中保持不变?
大多数 HTML 属性在 JSX 中保留原有名称。常见示例包括 id、src、href、alt、type、name、value、placeholder、disabled、hidden 以及所有 data-* 和 aria-* 属性。只有 HTML 名称与 DOM API 属性名不同的属性才需要更改:class 变为 className,for 变为 htmlFor,以及从全小写切换为驼峰命名的多词属性。
dangerouslySetInnerHTML 与将 HTML 转换为 JSX 相同吗?
不同。dangerouslySetInnerHTML 绕过 React 的渲染机制,将原始 HTML 直接注入 DOM,存在 XSS 安全风险。将 HTML 转换为 JSX 生成的是真实的 React 元素,经过 React 虚拟 DOM 处理,默认是安全的。对于你可控的静态标记,请使用 HTML 转 JSX 转换。只有在必须渲染来自外部无法转换为 JSX 的可信 HTML 时,才使用 dangerouslySetInnerHTML。