Skip to content

以下是完整的语法规则体系:


一、基本语法规则

1. 必须有一个根元素

JSX 表达式必须被单一父元素包裹,否则会语法错误。

jsx
// ❌ 错误:多个根元素
const App = () => {
  return (
    <h1>标题</h1>
    <p>段落</p>
  );
};

// ✅ 正确:使用 div 包裹
const App = () => {
  return (
    <div>
      <h1>标题</h1>
      <p>段落</p>
    </div>
  );
};

// ✅ 正确:使用 Fragment 避免额外 DOM 节点
const App = () => {
  return (
    <>
      <h1>标题</h1>
      <p>段落</p>
    </>
  );
};

2. 标签必须闭合

所有标签都必须有闭合标记,包括自闭合。

jsx
// ❌ 错误:未闭合
const App = () => {
  return <img src="logo.png">;
};

// ✅ 正确:自闭合标签用 />
const App = () => {
  return <img src="logo.png" />;
};

// ✅ 正确:普通标签必须有结束标签
const App = () => {
  return <div>内容</div>;
};

常见自闭合标签<img />, <input />, <br />, <hr />


二、JavaScript 表达式嵌入

1. 使用 {} 包裹表达式

在 JSX 中,任何 JavaScript 表达式都需用 {} 包裹。

jsx
const name = "React";
const age = 18;
const isActive = true;

const App = () => {
  return (
    <div>
      {/* 变量 */}
      <h1>{name}</h1>
      
      {/* 运算 */}
      <p>明年年龄:{age + 1}</p>
      
      {/* 函数调用 */}
      <p>{name.toUpperCase()}</p>
      
      {/* 条件渲染(三元表达式) */}
      <p>{isActive ? "活跃" : "离线"}</p>
      
      {/* 逻辑与(短路渲染) */}
      {isActive && <span>✓</span>}
    </div>
  );
};

2. 语句不支持

{} 中不能放置语句(如 iffor),只能放表达式。

jsx
// ❌ 错误:if 语句
const App = () => {
  return (
    <div>
      {if (isActive) { return <span>在线</span> }}
    </div>
  );
};

// ✅ 正确:三元表达式
const App = () => {
  return (
    <div>
      {isActive ? <span>在线</span> : <span>离线</span>}
    </div>
  );
};

// ✅ 正确:提前计算
const App = () => {
  let status;
  if (isActive) {
    status = <span>在线</span>;
  } else {
    status = <span>离线</span>;
  }
  return <div>{status}</div>;
};

三、属性(Props)规则

1. camelCase 命名

HTML 属性名需转换为驼峰命名法。

jsx
// ❌ 错误:HTML 属性名
const App = () => {
  return <div class="box" tabindex="0">内容</div>;
};

// ✅ 正确:React 属性名
const App = () => {
  return <div className="box" tabIndex="0">内容</div>;
};

// 常见转换表:
// class → className
// for → htmlFor
// tabindex → tabIndex
// onclick → onClick
// onchange → onChange

2. 动态属性

属性值可以是 JavaScript 表达式。

jsx
const url = "https://example.com";
const isDisabled = false;

const App = () => {
  return (
    <a href={url} target="_blank">
      链接
    </a>
  );
};

// 布尔属性:值为 true 时省略,false 时省略属性
const App = () => {
  return <button disabled={isDisabled}>点击</button>;
  // 当 isDisabled=false 时,等价于 <button>点击</button>
};

3. 特殊属性值

  • 字符串:可用双引号或单引号
  • 数字:必须用 {} 包裹
  • 样式对象style 接受对象,属性名用驼峰
jsx
const App = () => {
  return (
    <div
      className="container"  // 字符串
      data-id="123"          // 自定义属性可用连字符
      style={{              // 样式对象
        backgroundColor: 'lightblue',
        fontSize: 16
      }}
    >
      内容
    </div>
  );
};

四、子元素规则

1. 文本节点

文本可直接写在标签内,特殊字符自动转义。

jsx
const App = () => {
  return (
    <div>
      {/* 普通文本 */}
      普通文本
      
      {/* 自动转义:防止 XSS */}
      {"<script>alert('xss')</script>"}  {/* 显示为纯文本 */}
    </div>
  );
};

2. 列表渲染

数组自动展开,需为每个元素提供唯一 key

jsx
const items = ['Apple', 'Banana', 'Orange'];

const App = () => {
  return (
    <ul>
      {items.map((item, index) => (
        // ✅ 正确:使用唯一 key
        <li key={index}>{item}</li>
      ))}
    </ul>
  );
};

3. Fragment 分组

避免额外 DOM 节点。

jsx
const App = () => {
  return (
    <>
      <td>单元格1</td>
      <td>单元格2</td>
    </>
  );
};

五、注释方式

JSX 中注释需用大括号包裹 {/* ... */}

markdown
const App = () => {
  return (
    <div>
      {/* 这是单行注释 */}
      <h1>标题</h1>
      {/*
        多行注释
        可以写多行
      */}
    </div>
  );
};

六、常见陷阱与限制

1. className 不是 class

jsx
// ❌ 错误
<div class="box">内容</div>

// ✅ 正确
<div className="box">内容</div>

2. style 不是字符串

jsx
// ❌ 错误
<div style="color: red;">内容</div>

// ✅ 正确
<div style={{ color: 'red' }}>内容</div>

3. 事件处理函数不是字符串

jsx
// ❌ 错误
<button onclick="handleClick()">点击</button>

// ✅ 正确
<button onClick={handleClick}>点击</button>

4. **自闭合标签必须带 / **

jsx
// ❌ 错误
<br>

// ✅ 正确
<br />

5. ** 组件必须大写 **

jsx
// ❌ 错误:小写被视为 HTML 标签
const mycomponent = () => <div>内容</div>;

// ✅ 正确:大写开头
const MyComponent = () => <div>内容</div>;

七、** JSX 与 HTML 关键区别总结 **

markdown
| 特性     | HTML                  | JSX                             |
| -------- | --------------------- | ------------------------------- |
| 属性命名 | `class`, `tabindex`   | `className`, `tabIndex`         |
| 自闭合   | `<br>`                | `<br />`                        |
| 事件     | `onclick`             | `onClick`                       |
| 内联样式 | `style="color:red"`   | `style={{ color: 'red' }}`      |
| 注释     | `<!-- -->`            | `{/* */}`                       |
| 表达式   | 不支持                | 支持 `{expression}`             |
| 布尔属性 | `disabled="disabled"` | `disabled={true}``disabled` |

核心要点

  1. 本质是语法糖:JSX 编译为 React.createElement 调用
  2. JavaScript 优先:在 {} 中写 JavaScript 表达式
  3. HTML 兼容但有差异:属性用驼峰,事件处理用函数
  4. 必须单一根元素:使用 Fragment 避免多余 DOM
  5. key 很重要:列表渲染时提供唯一 key 提升性能

掌握这些规则,就能在 React 中自如地使用 JSX 构建 UI。