Skip to content

使用JSX书写标签语言

🌟 概述

  • 🔍 什么是JSX:JavaScript的语法扩展,允许在JS文件中编写类似HTML的标签
  • 🧩 核心理念:将渲染逻辑和UI标记放在一起,实现关注点的耦合
  • 🛠️ 使用场景:React组件中描述UI界面结构

🤔 为什么使用JSX

🔄 逻辑与标记的结合

  • 🧠 传统Web开发:HTML(内容)、CSS(样式)和JavaScript(逻辑)分离
  • 💡 React的创新:将相关联的渲染逻辑和标记放在同一个地方——组件
  • 🎯 优势
    • 修改时能保持逻辑和UI的同步
    • 相关代码紧密结合,无关代码相互隔离
    • 便于理解和维护组件
jsx
// 逻辑和UI标记在同一个组件中
function Button() {
  // 这里可以是事件处理、状态管理等逻辑
  const handleClick = () => alert('点击了按钮');
  
  // 返回UI标记
  return (
    <button onClick={handleClick}>
      点击我
    </button>
  );
}

📏 JSX规则

1️⃣ 只能返回单个根元素

  • ⚠️ 问题:不能直接并排返回多个标签
  • 解决方案:用一个父元素包裹多个元素
  • 🧩 常用包裹元素
    • <div>...</div> - 会生成实际DOM节点
    • <>...</> - Fragment片段,不会生成额外DOM节点
jsx
// ❌ 错误:多个并列元素没有共同父元素
function TodoList() {
  return (
    <h1>待办事项</h1>
    <ul>
      <li>学习React</li>
      <li>构建应用</li>
    </ul>
  );
}

// ✅ 正确:使用Fragment包裹
function TodoList() {
  return (
    <>
      <h1>待办事项</h1>
      <ul>
        <li>学习React</li>
        <li>构建应用</li>
      </ul>
    </>
  );
}

📌 原因:JSX在底层会被转换为JavaScript对象,函数不能返回多个对象(除非使用数组)

2️⃣ 标签必须闭合

  • 🔄 与HTML区别:JSX中所有标签必须正确闭合
  • 📝 两种闭合方式
    • 成对标签:<div>...</div>
    • 自闭合标签:<img />(注意末尾的/
jsx
// ❌ 错误:标签未闭合
<img src="image.jpg">
<li>项目一

// ✅ 正确:所有标签都闭合
<img src="image.jpg" />
<li>项目一</li>

3️⃣ 使用驼峰式命名法

  • 🔄 属性命名规则:大多数HTML属性在JSX中使用驼峰式命名
  • 🧠 原因:JSX更接近JavaScript而非HTML,遵循JavaScript变量命名规范
  • 📝 常见转换
    • classclassName
    • stroke-widthstrokeWidth
    • tabindextabIndex
jsx
// ❌ HTML风格
<div class="container">
  <label for="username">用户名:</label>
  <input tabindex="1" />
</div>

// ✅ JSX风格
<div className="container">
  <label htmlFor="username">用户名:</label>
  <input tabIndex={1} />
</div>

⚠️ 例外aria-*data-*属性保持原HTML格式,使用连字符形式

🔄 HTML转JSX

🛠️ 常见转换步骤

  1. 📦 添加根元素:使用<div><Fragment>包裹多个标签
  2. ✂️ 闭合所有标签:自闭合标签加/,非闭合标签添加结束标签
  3. 🔤 转换属性名:改为驼峰式命名(如classclassName

🧰 使用工具转换

  • 💡 推荐方法:使用在线JSX转换工具处理大段HTML
  • 🛠️ 常用工具转换工具可自动处理大部分规则
jsx
// HTML代码
<h1 class="title">标题</h1>
<img src="photo.jpg" alt="照片">

// 转换后的JSX
<h1 className="title">标题</h1>
<img src="photo.jpg" alt="照片" />

🧩 JSX实践示例

📋 完整组件示例

jsx
export default function Profile() {
  return (
    <>
      <h1>我的个人资料</h1>
      <img 
        src="https://i.imgur.com/yXOvdOSs.jpg" 
        alt="个人照片" 
        className="profile-photo" 
      />
      <ul>
        <li>姓名:张三</li>
        <li>职业:前端开发</li>
        <li>爱好:编程、阅读</li>
      </ul>
    </>
  );
}

🔍 JSX与HTML的主要区别对比

特性HTMLJSX
根元素可以有多个并列元素必须有单一根元素
标签闭合某些标签可以不闭合所有标签必须闭合
属性名称kebab-case (如font-size)camelCase (如fontSize)
类名属性classclassName
For属性forhtmlFor
事件处理onclick="handler()"onClick={handler}
样式属性style="color: red"style={{ color: 'red'}}

💡 最佳实践

📊 代码组织

  • 🧩 组件拆分:将大型JSX结构拆分为小组件,提高可维护性
  • 🔍 语义化标签:使用有意义的HTML标签(如<article><section>等)
  • 🧠 保持简洁:避免过深的JSX嵌套,保持组件结构清晰

🛠️ 调试技巧

  • 🔍 检查层级:确保JSX标签正确嵌套和闭合
  • 🐞 错误提示:注意控制台错误,React通常会提供有用的错误信息
  • 🧪 JSX验证工具:使用ESLint的React插件检查JSX语法

📝 总结

  • 🧩 JSX特点:将UI标记与JavaScript逻辑结合,实现关注点耦合
  • 📏 核心规则
    • 只能返回单个根元素
    • 所有标签必须闭合
    • 大多数属性使用驼峰命名法
  • 🔄 转换思路:HTML→JSX需要注意根元素、闭合标签和属性命名
  • 🚀 优势:让组件内的UI和逻辑保持同步,便于维护和理解

参考:React官方文档-使用JSX书写标签语言