Skip to content

JSX 的产物是 JavaScript 对象

既然 JSX 会被转换为 React.createElement(),那么这个函数执行后会返回什么呢?

答案是:一个普通的 JavaScript 对象

这个对象通常被称为“React 元素(React Element)”,它像一张蓝图,描述了我们希望在屏幕上看到的 UI 结构。以上面的 element 为例,React.createElement() 执行后得到的对象,大致会是这样:

javascript
{
  type: 'h1', 
  props: {
     className: 'greeting',
     children: 'Hello, world!'
  },
  // ... 其他内部属性
}

这个对象并不直接操作 DOM。它只是一个轻量的数据结构,用来告诉 React:“嘿,我想要渲染一个 h1 标签,它的 classgreeting,里面的内容是 Hello, world!。” React 会收集这些对象,构建出我们常说的虚拟 DOM(Virtual DOM),再高效地计算出如何更新真实的浏览器 DOM

所以,当我们编写 JSX 时,我们实际上是在用一种便捷的方式创建和组合 JavaScript 对象。

JSX 内部可以无缝嵌入 JavaScript 的全部能力

这或许是 JSX 作为“JavaScript 扩展”最有力的证明。在传统的模板引擎(如 HandlebarsEJS)中,我们通常只能使用其提供的特定语法来进行逻辑判断(如 {{#if}})或循环(如 {{#each}})。这些语法是受限的,它们自成体系,与 JavaScript 本身是割裂的。

JSX 完全不同。通过 {} 括号,我们可以在 JSX 中嵌入任何有效JavaScript 表达式。这意味着我们可以直接利用 JavaScript 语言的全部能力来构建动态 UI

变量与表达式

  • 我们可以直接引用变量,或进行简单的运算。
javascript
const user = { firstName: 'Harper', lastName: 'Perez' };
const element = <h1>Hello, {user.firstName} {user.lastName}!</h1>;

函数调用

  • 在渲染过程中执行函数,并将返回值作为内容。
javascript
function formatName(user) {
  return user.firstName + ' ' + user.lastName;
}

const element = <h1>Hello, {formatName(user)}!</h1>;

条件渲染

  • 利用三元运算符或逻辑与(&&)操作符,可以轻松实现条件渲染。
typescript
// 使用三元运算符
<div>
  {isLoggedIn ? <LogoutButton /> : <LoginButton />}
</div>

// 使用 && 操作符
<div>
  <h1>Hello!</h1>
  {unreadMessages.length > 0 &&
    <h2>
      You have {unreadMessages.length} unread messages.
    </h2>
  }
</div>

列表渲染

  • Array.prototype.map()JavaScript 的原生方法,在 JSX 中用于列表渲染是极其自然和常见的模式。map 方法返回一个由 JSX 元素构成的新数组,React 会将其渲染为列表。
typescript
const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
  <li key={number.toString()}>{number}</li>
);

// 最终渲染 <ul>{listItems}</ul>

结论

综上所述,JSX 的精妙之处在于它并非一种与 JavaScript 分离的模板技术。

  • 它是一种语法扩展,为 React.createElement() 提供了更具可读性和表现力的声明式写法。

  • 它的最终产物是纯粹的 JavaScript 对象,这构成了 React 虚拟 DOM 的基础。

  • 它允许我们无缝地利用 JavaScript 的全部功能,包括变量、函数、条件逻辑和循环,从而构建出复杂而动态的用户界面。

当我们说 JSXJavaScript 的扩展时,我们强调的是它与 JavaScript 语言的深度融合。这种融合打破了传统“逻辑层”与“视图层”之间的壁垒,为我们带来了一种更内聚、更强大的组件化开发体验。

不知道说啥了很无语了