此文章是翻译Introducing JSX这篇React(版本v16.2.0)官方文档。

Introducing JSX

考虑这个变量声明:

  1. const element = <h1>Hello , world!</h1>;

这个古怪的标签语法既不是字符串也不是HTML。

它就是JSX,它是JavaScript 的一个语法扩展。我们建议在React 中使用它去描述UI 的展示。JSX 可能会使你记起模版语言,但是它使用JavaScript 的所有功能。

JSX 产生React 的“element”。我们将在下一章 研究如何将它们渲染为DOM。接下来,你会了解对你使用React 所需要的基本的JSX 知识。

Why JSX?

React 包含这样一个事实,即渲染逻辑本质上与其他UI 逻辑耦合:事件如何处理,state 如何随时间变化,以及如何准备数据以显示。

相反,通过将标记和逻辑放在单独的文件中,而不是人为地分离技术,React 使用称为“组件”的松散耦合单元包含它们实现关注点分离(Sepatation of concerns)在之后的章节中,我们将回到到组件中,但是如果你还不习惯在js 中添加标记,那么这个讨论可能会让你信服。

React 不需要用JSX,但大多数人觉得它有助于视觉辅助当UI 工作在JavaScript代码时。它还允许作出React 以显示更多有用的错误和警告消息。

既然如此,我们开始吧!

Embedding Expressiongs in JSX

你可以在JSX 中,通过大括号来嵌入任何JavaScript expression

例如,2+2user.nameformatName(user) 都是有效的表达式:

  1. function formatName(user) {
  2. return user.firstName + ' ' + user.lastName;
  3. }
  4. const user = {
  5. firstName: 'Harper',
  6. lastName: 'Perez'
  7. };
  8. const element = (
  9. <h1>
  10. Hello, {formatName(user)}!
  11. </h1>
  12. );
  13. ReactDOM.render(
  14. element,
  15. document.getElementById('root')
  16. );

在CodePen 上尝试

为了可读性我们将JSX 拆分成多行。虽然它不是强制的,当在拆分JSX 为多行时,我们仍然建议使用括号去包括它,避免automatic semicolon insertion 陷阱。

JSX is an Expression Too

编译之后,JSX 表达式变成了常规的JavaScript 函数调用,并且对JavaScript 对象求值。

也就是说,你可以使用JSX,在if 语句和for 循环中,将它赋给一个变量,作为一个参数接受它,并从funcitons 中返回:

  1. function getGreeting(user) {
  2. if (user) {
  3. return <h1>Hello, {formatName(user)}!</h1>;
  4. }
  5. return <h1>Hello, Stranger</h1>;
  6. }

Specifying Attributes with JSX

你可以使用引号来指定字符串特性:

  1. const element = <div tabIndex="0"></div>;

在特性中,你也可以在通过使用大括号来包裹JavaScript 表达式:

  1. const element = <img src={user.avatarUrl}></img>

在特性中嵌入JavaScript 表达式时,不要在大括号上放置引号。 你应该使用引号(对于字符串值)或花括号(用于表达式),但不能同时使用在同一特性。

警告:

由于JSX 更接近JavaScript 而不是HTML,React DOM 使用camelCase 属性命名约定,而不是HTML 特性名字。

例如,class 在JSX 中变成了className,tabindex 变成了tabIndex

Specifying Children with JSX

如果一个标签为空,你应该使用/> 来闭合标签,类似XML:

  1. const element = <img src={user.avatarUrl} />;

JSX 标签可以包含子节点:

  1. const element = (
  2. <div>
  3. <h1>Hello </h1>
  4. <h2>Good to see you here.</h2>
  5. </div>
  6. );

JSX Prevents Injection Attacks

在JSX 中嵌入用户输入也是安全的:

  1. const title = response.potentiallyMaliciousInput
  2. // This is safe
  3. const element = <h1>{title}</h1>

默认,在渲染之前React DOM 转义在JSX 中嵌入的所有值。因此它能确保你永远不能注入任何没有在应用程序明确写入的东西。在渲染之前所有的东西都被转成字符串。这有助于防止(XSS(跨站脚本))[https://en.wikipedia.org/wiki/Cross-site_scripting]攻击。

JSX Represents Objects

Babel 将JSX 编译成通过React.createElement() 的方法调用:

下面两个例子是完全一样的:

  1. const element = (
  2. <h1 className="greeting">
  3. Hello, world!
  4. </h1>
  5. );
  1. const element = React.createElement(
  2. 'h1',
  3. {className: 'greeting'},
  4. 'Hello, world!'
  5. );

React.createElement() 执行一些检测来帮助你写出没有bug 的代码,但实际上它创建了如下一个对象:

  1. // Note: this structure is simplified
  2. const element = {
  3. type: 'h1',
  4. props: {
  5. className: 'greeting',
  6. children: 'Hello, world'
  7. }
  8. }

这些对象被称为”React elements”。你可以把它们想成描述你想要在屏幕上看的。React 读取这些对象并使用它们构成DOM 并保证它们更新。

在下一章中我们将继续探索渲染React 元素为DOM。

Tip:

我们建议在你的编辑器中“Babel” 语言定义 选项,以至于ES6 和JSX 代码正确高亮。本网站使用Oceanic Next 颜色主体来兼容它。