====== 第四章:JSX 详解 ====== ===== 4.1 什么是 JSX ===== JSX(JavaScript XML)是 React 中用于描述 UI 的语法扩展。它看起来像是 HTML,但实际上是 JavaScript。 const element =

Hello, world!

;
这段 JSX 代码会被 Babel 等工具转换为: const element = React.createElement('h1', null, 'Hello, world!'); **为什么要用 JSX**: * 直观:在 JavaScript 中直接描述 UI 结构 * 强大:可以使用 JavaScript 的全部能力 * 类型安全:编译时就能发现错误 ===== 4.2 JSX 语法规则 ===== **必须有一个根元素**: JSX 表达式必须有一个外层包裹元素。 // 正确 return (

标题

内容

); // 错误 - 没有根元素 return (

标题

内容

); // 使用 Fragment 作为根元素 return ( <>

标题

内容

);
**使用 className 代替 class**: class 是 JavaScript 的保留字,所以在 JSX 中使用 className。 // 正确
内容
// 错误
内容
**使用 camelCase 属性名**: HTML 属性在 JSX 中使用 camelCase。 // HTML // JSX **标签必须闭合**: 所有标签都必须正确闭合。 // 正确 照片 // 错误 照片 ===== 4.3 在 JSX 中嵌入表达式 ===== 使用花括号 {} 在 JSX 中嵌入 JavaScript 表达式。 **变量和表达式**: const name = 'React'; const element =

Hello, {name}!

; const sum = 1 + 2; const result =

1 + 2 = {sum}

; const element =

2 + 2 = {2 + 2}

;
**函数调用**: function formatName(user) { return user.firstName + ' ' + user.lastName; } const user = { firstName: '张', lastName: '三' }; const element =

{formatName(user)}

;
**条件渲染**: const isLoggedIn = true; // 使用三元运算符 const element = (
{isLoggedIn ? : }
); // 使用逻辑与运算符 const element = (
{isLoggedIn && }
); // 使用变量 let content; if (isLoggedIn) { content = ; } else { content = ; } const element =
{content}
;
===== 4.4 JSX 中的属性 ===== **字符串字面量**: const element =
; const element = ;
**嵌入表达式**: const avatarUrl = 'https://example.com/avatar.jpg'; const element = ; const element =
;
**展开属性**: const props = { firstName: '张', lastName: '三', age: 25 }; const element = ; // 等同于 const element = ; ===== 4.5 JSX 防止 XSS 攻击 ===== React DOM 在渲染之前会转义所有嵌入的值。这确保了你永远不会注入未转义的内容。 const title = response.potentiallyMaliciousInput; // 这是安全的 const element =

{title}

;
默认情况下,React DOM 会将所有内容在渲染前进行转义。所有的内容在渲染之前都被转换成了字符串。这样可以有效地防止 XSS(跨站脚本)攻击。 **危险地设置 HTML**: 有时你需要设置 HTML 内容(如富文本编辑器),这时可以使用 dangerouslySetInnerHTML: function MyComponent() { const htmlContent = { __html: '粗体文本' }; return
; } ⚠️ 警告:使用 dangerouslySetInnerHTML 存在安全风险,确保内容是可信的。 ===== 4.6 JSX 表示对象 ===== Babel 会将 JSX 编译为 React.createElement() 调用。 这两个例子完全等同: const element = (

Hello, world!

); const element = React.createElement( 'h1', { className: 'greeting' }, 'Hello, world!' );
React.createElement() 执行后返回一个类似这样的对象: const element = { type: 'h1', props: { className: 'greeting', children: 'Hello, world!' } }; 这样的对象被称为"React 元素",它描述了你希望在屏幕上看到的内容。React 读取这些对象,用它们来构建 DOM 并保持其更新。 ===== 4.7 注释 ===== 在 JSX 中使用注释: const element = (
{/* 这是注释 */}

标题

{/ 多行 注释 /}
);
===== 4.8 JSX 的 children ===== **字符串**: const element =
Hello World
;
**JSX 元素**: const element = (
Hello World
);
**混合类型数组**: const items = ['苹果', '香蕉', '橙子']; const element = ( ); **函数作为 children**: function Repeat(props) { let items = []; for (let i = 0; i < props.numTimes; i++) { items.push(props.children(i)); } return
{items}
; } function ListOfTenThings() { return ( {(index) =>
这是第 {index} 项
}
); }
===== 4.9 布尔值、Null 和 Undefined ===== false、null、undefined 和 true 都是有效的 children,但它们不会被渲染。 // 以下都会渲染相同的结果
{false}
{null}
{undefined}
{true}
这在条件渲染中很有用:
{showHeader &&
}
**注意**:数字 0 会被渲染出来,要注意这种情况: // 如果 items.length 为 0,会显示 0
{items.length && }
// 正确做法
{items.length > 0 && }
===== 4.10 Fragment ===== Fragment 允许你将子元素列表分组,而无需向 DOM 添加额外节点。 import React from 'react'; function Example() { return ( ); } // 短语法 function Example() { return ( <> ); } 带 key 的 Fragment: function Glossary(props) { return (
{props.items.map(item => (
{item.term}
{item.description}
))}
); }
===== 4.11 总结 ===== 本章深入讲解了 JSX 的各个方面: * JSX 的基本语法规则 * 嵌入表达式 * 属性设置 * XSS 防护 * children 的处理 * Fragment 的使用 掌握 JSX 是 React 开发的基础。下一章我们将学习组件的概念和用法。