HTML转JSX转换器

把 HTML 片段粘进来,本页按 React 的属性命名约定改写成 JSX:保留字属性换名、多词属性改小驼峰、无结束标签的元素补自闭合、style 字符串转对象。全部在浏览器本地完成,源码不上传服务器。

转换口径:属性名按 React 命名表改写(class→className、for→htmlFor、readonly→readOnly 等),data-* 与 aria-* 原样保留,style 字符串转成对象写法,void 元素补自闭合斜杠。

使用方法

HTML转JSX转换器是「粘贴、设缩进、点转换」四步:

  1. 在左边「待转换的 HTML」里粘贴你的片段。打开页面就有一份演示片段(div、img、label、input、br 共五行),可直接改。
  2. 「缩进空格数」填 2~8,默认 2。它决定每行前面补几个空格,只影响排版,不影响语义。
  3. 两个开关按需勾:想把 value、checked 改成非受控写法就勾第一项;默认已勾第二项,会把 <!-- 注释 --> 转成 JSX 注释写法。
  4. 点「转换」,或在文本框里按 Ctrl/Cmd + Enter(Enter 留给换行)。结果出现在右边,按「复制结果」整段拿走。

HTML转JSX转换器能解决什么

它解决「把设计稿或旧页面的 HTML 搬进 React 组件时,属性名一个个手改」的重复劳动:

  • 保留字冲突:class 和 for 在 JavaScript 里是关键字,直接搬到 JSX 会报错,本页统一改成 className、htmlFor。
  • 多词属性大小写:readonly、maxlength、tabindex 这类在 JSX 里要写成小驼峰 readOnly、maxLength、tabIndex,手工改很容易漏掉一个。
  • 标签必须闭合:HTML 里 <br>、<img>、<input> 可以不写结束标签,JSX 里必须写成 <br /> 形式,否则解析失败。
  • style 写法不同:HTML 的 style="color:red;font-size:14px" 在 JSX 里必须是对象 style={{color:'red',fontSize:'14px'}},字符串会直接报错。
  • 缩进重排:从浏览器「检查元素」里复制出来的代码经常缩进混乱,转换时按标签嵌套层级重排一遍,粘进组件文件不用再手工对齐。

本页不做的事:不做语法校验,转换结果不保证一定能通过 ESLint;不处理 <script> 里的 JS 逻辑;不帮你补 onChange;不做 JSX 转回 HTML 的反向转换。它改的是标签与属性的写法,不是代码逻辑。

原理和变量

① 用了哪个具体函数:属性解析用一次 String.prototype.replace 配合捕获组正则,把每个「属性名 = 属性值」逐个抽出来,再查一张二十余条的属性映射表改写;标签是否自闭合由一份十三项的 void 元素名单决定;缩进按每行开标签与闭标签的数量差重排。整页没有引入 Babel、htmlparser2 或任何解析器,只有正则分词加逐行计数。

② 关键参数为什么这样取:只改属性名、不改属性顺序,是为了让转换结果与原 HTML 一一对应,方便你对照 diff 时一眼看出改了什么。data-* 与 aria-* 这类带连字符的属性原样保留,因为 JSX 本身就支持连字符属性名,改写成驼峰反而会破坏无障碍语义与测试选择器。style 必须转成对象,因为 JSX 的 style 只接受对象,传字符串会直接抛错。

③ 遵循哪个标准:属性名改写遵循 React 官方 JSX 的 DOM 属性命名约定——避开 class、for 这两个 JavaScript 保留字,其余多词属性统一改小驼峰;void 元素名单取自 HTML 规范中「不允许有结束标签」的元素集合;缩进只是排版,不参与语义,所以放在最后一步处理。

④ 输入怎么变成输出:演示片段里 <div class="card" data-id="1"> 变成 <div className="card" data-id="1">;<label for="user-name"> 变成 <label htmlFor="user-name">;<input type="text" value="小明" readonly> 变成 <input type="text" value="小明" readOnly />;<br> 变成 <br />;data-id 保持不变。

⑤ 边界与阈值:缩进空格数限 2~8,默认 2;单次输入超过 20000 字符会提示「内容过长,请分段转换」;输入为空或只含空白会提示「请先粘贴 HTML 片段」。style 值按分号拆项、每项按第一个冒号拆键值,若某项里含有冒号之外无法拆分的片段(例如 background:url(...) 这种本身含冒号的值),拆分可能偏移,需要你手动复核。

⑥ 常见误用的正确解释:以为转换完就能直接放进组件是最大的误区——value 属性若没有配套的 onChange,React 会把它当成受控组件并给出警告,此时应该勾上「改 defaultValue」或手工补上 onChange。另一个常见错误是自闭合后又补了结束标签,写成 <br /></br>。

完整示例(数值仅作演示)

演示输入(缩进 2 个空格、开启注释转换、不开启 defaultValue):

<div class="card" data-id="1">
  <img src="cover.png" alt="封面">
  <label for="user-name">姓名</label>
  <input type="text" value="小明" readonly>
  <br>
</div>

逐行推导后的输出:

  • 第一行:class → className,data-id 保留 → <div className="card" data-id="1">。
  • 第二行:img 属于无结束标签元素,补斜杠 → <img src="cover.png" alt="封面" />。
  • 第三行:for → htmlFor → <label htmlFor="user-name">姓名</label>。
  • 第四行:readonly → readOnly,input 补斜杠 → <input type="text" value="小明" readOnly />。
  • 第五行:br 补斜杠 → <br />。

合起来就是右侧默认展示的那五行的结果,可与默认输出逐字核对。

输入范围与对照表

下表列出本页会主动改写的属性名映射,前 12 行是最常遇到的,后 4 行继续补充;带连字符的属性与未知属性一律原样保留。

HTML 属性到 JSX 属性的改写映射(部分)
HTML 属性JSX 属性改写原因
classclassNameclass 是 JavaScript 关键字
forhtmlForfor 是 JavaScript 关键字
tabindextabIndex多词属性改小驼峰
readonlyreadOnly多词属性改小驼峰
maxlengthmaxLength多词属性改小驼峰
minlengthminLength多词属性改小驼峰
autofocusautoFocus多词属性改小驼峰
autoplayautoPlay多词属性改小驼峰
colspancolSpan多词属性改小驼峰
rowspanrowSpan多词属性改小驼峰
enctypeencType多词属性改小驼峰
accesskeyaccessKey多词属性改小驼峰

映射表之外还有 srcset、novalidate、crossorigin、referrerpolicy 等十余条同样按小驼峰改写;未知属性与 data-*、aria-* 一律不动。

结果边界和舍入

输出性质:转换结果是纯文本字符串,不含引号包裹,可直接粘进 .jsx 文件。属性值的引号保持原样(双引号还是双引号),只有 style 会被改写为对象写法。

什么时候会提示:输入为空或只有空白时提示「请先粘贴 HTML 片段」;输入超过 20000 字符时提示「内容过长,请分段转换」;缩进不在 2~8 之间时提示并回退到 2。本页不做语法校验,所以非法的标签嵌套不会报错,只会原样输出。

精度与确定性:转换是纯字符串改写,没有任何数值计算,因此不存在舍入问题;同样的输入必然得到同样的输出,结果可重复。

结果性质:这是写法层面的机械转换,不是代码审查。转换后仍请用编辑器的语法检查、ESLint 和一次真实渲染来验收,尤其是 style 与事件属性这两类。

常见问题

为什么不直接把 class 保留下来?

因为 class 是 JavaScript 的保留字,JSX 最终要编译成 JavaScript 函数调用,用 class 作属性名会触发语法错误,所以 React 约定改叫 className。

data-* 和 aria-* 为什么没被改写?

JSX 支持带连字符的属性名,改写反而会破坏无障碍语义和自动化测试用的选择器,所以本页对这两类属性一律原样保留。

style 属性为什么要变成对象?

JSX 的 style 只接受对象,传字符串会在运行时直接报错。本页按分号拆项、按第一个冒号拆键值,再把属性名改小驼峰,拼成对象写法。

value 什么时候该改成 defaultValue?

当表单元素没有配套 onChange 时。带 value 而没有 onChange 会被 React 视为受控组件并给出警告,勾上「改 defaultValue」即可变成非受控写法。

缩进用制表符可以吗?

本页统一输出空格,缩进空格数可在 2~8 之间选。需要制表符的话,粘进编辑器后用它自带的缩进转换功能换一次即可。

HTML 注释是怎么处理的?

默认开启转换,注释会被改写成 JSX 支持的注释写法。若你希望保留原始 HTML 注释文本,取消勾选「把 HTML 注释转成 JSX 注释」即可。

输入很长会被截断吗?

不会截断,但超过 20000 字符会提示「内容过长,请分段转换」并停止处理,避免一次处理过大文本造成卡顿。分几段转换再拼接即可。

我的源码会被上传吗?

不会。转换完全在浏览器内完成,不发起任何网络请求,刷新即清空。可以在 Network 面板复查,点「转换」时不会有任何请求发出。

相关工具