将 HTML 模板迁移到 React 意味着将标记重写为 JSX。虽然 JSX 看起来类似 HTML,但有关键差异,如果忽略这些差异会导致编译错误。本指南涵盖了你需要做的所有更改。
为什么 JSX 与 HTML 不同
JSX 不是 HTML。它是 JavaScript 的语法扩展,编译为 React.createElement() 调用。因为 JSX 存在于 JavaScript 中,它遵循 JavaScript 规则——一些 HTML 属性名与 JavaScript 保留字冲突。
如果在 JSX 中使用标准的 HTML 属性如 class 或 for,编译器会抛出错误。理解这些差异对于任何 React 迁移都至关重要。
关键属性差异
以下是从 HTML 转换为 JSX 时最常见的需要更改的属性:
| HTML | JSX | 原因 |
|---|---|---|
class | className | class 是 JS 保留字 |
for | htmlFor | for 是 JS 保留字 |
tabindex | tabIndex | JSX 使用 camelCase |
readonly | readOnly | JSX 使用 camelCase |
maxlength | maxLength | JSX 使用 camelCase |
onclick | onClick | JSX 使用 camelCase |
style="color: red" | style={{'{'}color: "red"{'}'} | JSX 的 style 是对象 |
Style 属性
在 HTML 中,style 是字符串。在 JSX 中,它是一个 JavaScript 对象,属性名使用 camelCase:
<!-- HTML -->
<div style="background-color: #f0f0f0; font-size: 14px; margin-top: 20px;">
Hello
</div>
// JSX
<div style={{ backgroundColor: "#f0f0f0", fontSize: "14px", marginTop: "20px" }}>
Hello
</div>所有 CSS 属性名必须使用 camelCase:background-color 变为 backgroundColor,font-size 变为 fontSize,z-index 变为 zIndex。
自闭合标签
HTML 允许某些标签不闭合(空元素)。在 JSX 中,每个标签都必须显式关闭:
<br>→<br /><hr>→<hr /><img src="...">→<img src="..." /><input type="text">→<input type="text" /><meta charset="utf-8">→<meta charSet="utf-8" />
<!-- HTML -->
<img src="photo.jpg" alt="Photo">
<input type="email" placeholder="Email">
<br>
// JSX
<img src="photo.jpg" alt="Photo" />
<input type="email" placeholder="Email" />
<br />事件处理器
HTML 使用小写事件属性作为字符串。JSX 使用 camelCase 并传入函数引用:
<!-- HTML -->
<button onclick="handleClick()">Click me</button>
<input onchange="handleChange()" onfocus="handleFocus()">
// JSX
<button onClick={handleClick}>Click me</button>
<input onChange={handleChange} onFocus={handleFocus} />在 JSX 中,事件处理器接收的是 SyntheticEvent,而不是原生 DOM 事件。React 会跨浏览器规范化事件以保持一致行为。
JSX 中的注释
HTML 注释(<!-- ... -->)在 JSX 中无效。需要使用 JavaScript 块注释包裹在花括号中:
<!-- HTML comment -->
<div>Hello</div>
// JSX comment
<div>
{/* This is a JSX comment */}
Hello
</div>常见陷阱
- 忘记
className——最常见的迁移错误。搜索替换所有class=为className= - 内联样式使用字符串——
style="margin: 10px"会抛出错误;需要使用对象 - 未闭合标签——没有自闭合斜杠的
<img>或<br>会报错 - 相邻元素——JSX 必须返回单个根元素;用
<>...</>(Fragment)包裹兄弟元素 - 布尔属性——HTML 的
disabled在 JSX 中相同,或显式写为disabled={true} - 文本中的花括号——字面量
{和}必须使用{'{'}和{'}'}表示
// Fragment wrapper for multiple elements
function App() {
return (
<>
<Header />
<Main />
<Footer />
</>
);
}自动化迁移
手动将大型 HTML 文件转换为 JSX 容易出错。我们的 HTML to JSX 转换器自动处理所有转换——class 到 className、style 字符串到对象、自闭合标签等。