当前位置: 首页 > news >正文

JSX 语法

下面,我们来系统的梳理关于 JSX 语法 的基本知识点:


一、JSX 核心概念

1.1 什么是 JSX?

JSX (JavaScript XML) 是 React 的核心语法扩展,它允许你在 JavaScript 代码中编写类似 HTML 的结构。JSX 不是字符串也不是 HTML,而是JavaScript 的语法糖,最终会被编译为 React.createElement() 调用。

// JSX 写法
const element = <h1 className="title">Hello, React!</h1>;// 编译后的 JavaScript
const element = React.createElement('h1',{ className: 'title' },'Hello, React!'
);

1.2 为什么使用 JSX?

  • 声明式UI:直观描述 UI 结构
  • 代码可读性:类似 HTML 的语法更易理解
  • 表达能力:结合 JavaScript 的强大功能
  • 类型安全:与 TypeScript 完美集成
  • 开发效率:减少模板代码量

二、JSX 基础语法

2.1 基本规则

  • 必须有一个根元素:使用 <></> 片段避免多余 DOM
// 错误:多个根元素
const invalid = (<h1>Title</h1><p>Content</p>
);// 正确:单根元素或片段
const valid = (<><h1>Title</h1><p>Content</p></>
);
  • 标签必须闭合
// 自闭合标签
<img src="logo.png" alt="Logo" />// 常规标签
<div>Content</div>

2.2 嵌入表达式

使用 {} 嵌入任何 JavaScript 表达式:

const user = {name: 'Alice',avatarUrl: 'avatar.jpg'
};const element = (<div><h1>Hello, {user.name}!</h1><img src={user.avatarUrl} alt="Avatar" /><p>2 + 2 = {2 + 2}</p><p>当前时间: {new Date().toLocaleTimeString()}</p></div>
);

2.3 属性命名规范

JSX 使用 camelCase 命名属性:

HTML 属性JSX 属性说明
classclassNameCSS 类名
forhtmlFor标签的 for 属性
tabindextabIndex标签顺序
onclickonClick点击事件处理
stylestyle接受对象而非字符串
<div className="container"tabIndex={1}style={{ backgroundColor: 'lightblue',padding: '20px'}}
>Content
</div>

三、JSX 高级特性

3.1 条件渲染

多种条件渲染模式:

// 1. 三元表达式
const message = (<div>{isLoggedIn ? (<WelcomeMessage user={user} />) : (<LoginButton />)}</div>
);// 2. 逻辑与(&&)短路
const notification = (<div>{hasUnreadMessages && <NotificationBadge count={unreadCount} />}</div>
);// 3. 立即执行函数
const complexCondition = (<div>{(() => {if (status === 'loading') return <Spinner />;if (status === 'error') return <ErrorDisplay />;return <Content data={data} />;})()}</div>
);

3.2 列表渲染

使用 map() 渲染列表,必须提供 key 属性:

const products = [{ id: 1, name: 'Laptop', price: 999 },{ id: 2, name: 'Phone', price: 699 },{ id: 3, name: 'Tablet', price: 499 }
];const productList = (<ul>{products.map(product => (<li key={product.id}><h3>{product.name}</h3><p>Price: ${product.price}</p></li>))}</ul>
);

key 的重要性:帮助 React 识别元素变化,提高 diff 算法效率

3.3 事件处理

使用 camelCase 命名事件,传递函数而非字符串:

function handleClick(e) {e.preventDefault();console.log('Button clicked!');
}const button = (<button onClick={handleClick}>Click Me</button>
);

3.4 组件组合

JSX 支持组件嵌套和插槽模式:

// 父组件
function Card({ title, children }) {return (<div className="card"><h2>{title}</h2><div className="card-content">{children}  {/* 子内容插槽 */}</div></div>);
}// 使用
const app = (<Card title="User Profile"><img src="avatar.jpg" alt="Avatar" /><p>Name: John Doe</p><p>Email: john@example.com</p></Card>
);

四、JSX 底层原理

4.1 JSX 编译过程

JSX 通过 Babel 编译为 React.createElement 调用:

// 源代码
const element = <div className="container">Hello</div>;// 编译后
const element = React.createElement('div',{ className: 'container' },'Hello'
);

4.2 React 元素对象

createElement 返回 React 元素对象:

{$$typeof: Symbol(react.element),type: 'div',key: null,ref: null,props: {className: 'container',children: 'Hello'},_owner: null,_store: {}
}

4.3 虚拟 DOM 工作原理

JSX
React.createElement
React元素对象
虚拟DOM树
Reconciliation
DOM更新

五、JSX 最佳实践与陷阱

5.1 最佳实践

  1. 保持 JSX 简洁:复杂逻辑提取到函数/组件
  2. 使用片段:避免不必要的 <div> 嵌套
  3. 条件渲染优先:使用 && 和三元表达式
  4. key 属性:列表项必须使用稳定唯一标识
  5. 组件拆分:单个组件不超过 200 行 JSX

5.2 常见陷阱

// 陷阱1:直接渲染对象
const user = { name: 'Alice' };
<div>{user}</div> // 错误!应使用 {user.name}// 陷阱2:style 属性使用字符串
<div style="color: red"> // 错误!
<div style={{ color: 'red' }}> // 正确// 陷阱3:未转义用户输入
<div>{userInput}</div> // 危险!可能XSS攻击
<div>{sanitize(userInput)}</div> // 安全做法// 陷阱4:忘记绑定this
<button onClick={this.handleClick}>Click</button> // 类组件中需绑定

六、JSX 与 TypeScript

6.1 类型注解

interface UserCardProps {name: string;age: number;isAdmin?: boolean; // 可选属性
}function UserCard({ name, age, isAdmin = false }: UserCardProps) {return (<div className="user-card"><h2>{name} {isAdmin && <span>(Admin)</span>}</h2><p>Age: {age}</p></div>);
}

6.2 泛型组件

interface ListProps<T> {items: T[];renderItem: (item: T) => React.ReactNode;
}function List<T>({ items, renderItem }: ListProps<T>) {return (<ul>{items.map((item, index) => (<li key={index}>{renderItem(item)}</li>))}</ul>);
}// 使用
<List items={['React', 'Vue', 'Angular']} renderItem={(item) => <strong>{item}</strong>} 
/>

七、实战练习

7.1 转换练习

将以下 HTML 转换为正确 JSX:

<div class="profile"><img src="user.jpg" alt="User photo"><h1 id="username">John Doe</h1><ul class="features"><li>React Developer</li><li>UI Designer</li></ul><button onclick="handleClick()">Follow</button>
</div>
查看答案
<div className="profile"><img src="user.jpg" alt="User photo" /><h1 id="username">John Doe</h1><ul className="features"><li>React Developer</li><li>UI Designer</li></ul><button onClick={handleClick}>Follow</button>
</div>

7.2 组件练习

创建可复用的 Accordion 组件:

function Accordion({ title, children }) {const [isOpen, setIsOpen] = useState(false);return (<div className="accordion"><div className="header" onClick={() => setIsOpen(!isOpen)}><h3>{title}</h3><span>{isOpen ? '▲' : '▼'}</span></div>{isOpen && <div className="content">{children}</div>}</div>);
}// 使用
<Accordion title="React 知识"><p>JSX 是 React 的核心语法</p><p>组件是构建 UI 的基础单元</p>
</Accordion>

八、总结

  • JSX 是 React 的声明式 UI 语法糖
  • 使用 {} 嵌入表达式,camelCase 命名属性
  • 掌握条件渲染、列表渲染和组件组合模式
  • 理解 JSX 编译为 React.createElement 的底层原理
  • 遵循最佳实践避免常见陷阱
  • 结合 TypeScript 增强类型安全
http://www.dtcms.com/a/277894.html

相关文章:

  • 【前端知识】移动端APP原生应用与H5交互底层逻辑
  • Dubbo跨越分布式事务的最终一致性陷阱
  • 有效感受野(ERF)可视化工具
  • hash表的模拟--开放定址法
  • 如何将本地代码同步到远程Github仓库
  • 【Docker基础】Dockerfile指令速览:环境与元数据指令详解
  • OSPF与BGP的联动特性
  • Utils系列之内存池(MultiSizePool)
  • 【MLLM】多模态理解GLM-4.1V-Thinking模型
  • OpenVela 日志系统:从配置到落地的实操手册
  • Python装饰器(自定义装饰器和3个内置装饰器)
  • Java反射机制深度解析
  • 树莓派5-ollama-linux-arm64.tgz 下载
  • AEC线性处理
  • 在 OCI 生成式 AI 上搭一个「指定地区拉面店 MCP Server」——从 0 到 1 实战记录
  • 《数据库》MySQL事务
  • gcc 源码阅读--C语言预处理
  • (一)SAP Group Reporting (GR) 集团财务合并解决方案套件概述
  • 构造函数延伸应用
  • [Python 基础课程]字典
  • 代码随想录算法训练营第十七天
  • spring--@Autowired
  • LlamaIndex Querying 自定义查询
  • JavaScript数据结构算法
  • js入门01
  • YOLOv5目标检测标准化流程
  • 013_流式输出与实时响应
  • 【SSM】SpringBoot 实现邮件发送
  • Typecho博客新文章自动添加“New“标签的实现方案
  • 热点代码探测确定何时JITTest01