JSX
用纯 JavaScript 构建哪怕是一小块 UI 都需要拆分成多个步骤:创建元素、设置类名、设置文本,最后把它挂到页面上。标记和驱动它的代码分开放着,UI 越复杂就越难保持同步。JSX 解决了这个问题:标记直接写在 JavaScript 里,紧密到足以让你随时混用它们,而不用分开放模板和脚本。
JavaScript 中的标记
既然 JSX 是 JavaScript,你可以把任何 JavaScript 表达式扔进去,只需用花括号 {} 包起来。变量、函数调用、一点儿数学计算,任何你需要的值,都可以直接塞到标记里,代替你原本写的静态文本。
const name = 'Ada'
return <p className="greeting">Hello, {name}</p>这里 {name} 会在渲染时被 name 变量的值替换掉,所以页面显示的是 "Hello, Ada"。花括号外的所有东西都是标记;花括号内的,你又回到了纯 JavaScript。
JSX 有几条规则。大多数属性用 camelCase 而不是 HTML 的小写加连字符形式,所以是 className、htmlFor 和 tabIndex,而不是 class、for 和 tabindex;ARIA 和 data- 属性保持连字符,比如 aria-hidden 和 data-testid。每个标签都要闭合,包括在 HTML 中会留开的那些,所以 <img /> 和 <br /> 都要加上那个反斜杠。一个组件只能返回一个根元素。如果你需要返回并排的两个元素又不想用额外的 <div> 包装它们,用 fragment 包起来,写法是空的尖括号:
return (
<>
<h1>Title</h1>
<p>Some text</p>
</>
)JSX 与 HTML 的差异
JSX 看起来接近 HTML,但差异足够细微,以至于你没察觉到时就被绊倒了。属性名是第一个差异:class 变成 className,因为 class 在 JavaScript 中是保留字。style 属性也不同:在 HTML 中它是 CSS 字符串,在 JSX 中它接收一个 JavaScript 对象,属性名用 camelCase,值是字符串。
<div style={{ backgroundColor: 'lightblue', fontSize: '18px' }}>Styled</div>外层的 {} 就是嵌入任何表达式的那个,内层的 {} 是被嵌入的对象字面量,这就是为什么 JSX 中的 style 属性最后会有两个花括号连在一起。
另一个差异是 {} 内部允许什么。它只接受 表达式,也就是产生值的东西,像变量、函数调用或三元操作符。它不接受语句,所以 if 或 for 循环不能直接放在你标记里的花括号中。当你需要那种逻辑时,在 return 之前运行它,然后嵌入结果。
幕后来看,JSX 在到达浏览器前被编译成纯 JavaScript 函数调用。这更多是工具细节,你日常中不会频繁想到,Beyond the basics 这一章在 React 的其他内容都说清楚后会回到这点。
{} 是你从标记内部回到 JavaScript 的门道。这些花括号之间的任何东西都是一个值、一个变量、一个计算、一个函数调用,它会直接放到页面上。其他的都是由此而来:className 替代 class,每个标签都闭合,一个 return 返回一个根元素。 接下来:样式组件,让这些元素有外观。

