在 JSX 中通过大括号使用 JavaScript | JavaScript in JSX with Curly Braces

JSX lets you write HTML-like markup inside a JavaScript file, keeping rendering logic and content in the same place. Sometimes you will want to add a little JavaScript logic or reference a dynamic property inside that markup. In this situation, you can use curly braces in your JSX to open a window to JavaScript. JSX 允许你在 JavaScript 中编写类似 HTML 的标签,从而使渲染的逻辑和内容可以写在一起。有时候,你可能想要在标签中添加一些 JavaScript 逻辑或者引用动态的属性。这种情况下,你可以在 JSX 的大括号内来编写 JavaScript。

你将会学习到

  • How to pass strings with quotes
  • 如何使用引号传递字符串
  • How to reference a JavaScript variable inside JSX with curly braces
  • 在 JSX 的大括号内引用 JavaScript 变量
  • How to call a JavaScript function inside JSX with curly braces
  • 在 JSX 的大括号内调用 JavaScript 函数
  • How to use a JavaScript object inside JSX with curly braces
  • 在 JSX 的大括号内使用 JavaScript 对象

使用引号传递字符串 | Passing strings with quotes

When you want to pass a string attribute to JSX, you put it in single or double quotes: 当你想把一个字符串属性传递给 JSX 时,把它放到单引号或双引号中:

export default function Avatar() {
  return (
    <img
      className="avatar"
      src="https://i.imgur.com/7vQD0fPs.jpg"
      alt="Gregorio Y. Zara"
    />
  );
}

Here, "https://i.imgur.com/7vQD0fPs.jpg" and "Gregorio Y. Zara" are being passed as strings. 这里的 "https://i.imgur.com/7vQD0fPs.jpg""Gregorio Y. Zara" 就是被作为字符串传递的。

But what if you want to dynamically specify the src or alt text? You could use a value from JavaScript by replacing " and " with { and }: 但是如果你想要动态地指定 srcalt 的值呢?你可以 {} 替代 "" 以使用 JavaScript 变量

export default function Avatar() {
  const avatar = 'https://i.imgur.com/7vQD0fPs.jpg';
  const description = 'Gregorio Y. Zara';
  return (
    <img
      className="avatar"
      src={avatar}
      alt={description}
    />
  );
}

Notice the difference between className="avatar", which specifies an "avatar" CSS class name that makes the image round, and src={avatar} that reads the value of the JavaScript variable called avatar. That’s because curly braces let you work with JavaScript right there in your markup! 请注意 className="avatar"src={avatar} 之间的区别,className="avatar" 指定了一个就叫 "avatar" 的使图片在样式上变圆的 CSS 类名,而 src={avatar} 这种写法会去读取 JavaScript 中 avatar 这个变量的值。这是因为大括号可以使你直接在标签中使用 JavaScript!

使用大括号:一扇进入 JavaScript 世界的窗户 | Using curly braces: A window into the JavaScript world

JSX is a special way of writing JavaScript. That means it’s possible to use JavaScript inside it—with curly braces { }. The example below first declares a name for the scientist, name, then embeds it with curly braces inside the <h1>: JSX 是一种编写 JavaScript 的特殊方式。这为在大括号 { } 中使用 JavaScript 带来了可能。下面的示例中声明了科学家的名字,name,然后在 <h1> 后的大括号内嵌入它:

export default function TodoList() {
  const name = 'Gregorio Y. Zara';
  return (
    <h1>{name}'s To Do List</h1>
  );
}

Try changing the name’s value from 'Gregorio Y. Zara' to 'Hedy Lamarr'. See how the list title changes? 试着将 name 的值从 'Gregorio Y. Zara' 更改成 'Hedy Lamarr'。看看这个 To Do List 的标题将如何变化?

Any JavaScript expression will work between curly braces, including function calls like formatDate(): 大括号内的任何 JavaScript 表达式都能正常运行,包括像 formatDate() 这样的函数调用:

const today = new Date();

function formatDate(date) {
  return new Intl.DateTimeFormat(
    'zh-CN',
    { weekday: 'long' }
  ).format(date);
}

export default function TodoList() {
  return (
    <h1>To Do List for {formatDate(today)}</h1>
  );
}

可以在哪使用大括号 | Where to use curly braces

You can only use curly braces in two ways inside JSX: 在 JSX 中,只能在以下两种场景中使用大括号:

  1. As text directly inside a JSX tag: <h1>{name}'s To Do List</h1> works, but <{tag}>Gregorio Y. Zara's To Do List</{tag}> will not.
  • 用作 JSX 标签内的文本<h1>{name}'s To Do List</h1> 是有效的,但是 <{tag}>Gregorio Y. Zara's To Do List</{tag}> 无效。
  1. As attributes immediately following the = sign: src={avatar} will read the avatar variable, but src="{avatar}" will pass the string "{avatar}".
  • 用作紧跟在 = 符号后的 属性src={avatar} 会读取 avatar 变量,但是 src="{avatar}" 只会传一个字符串 {avatar}

使用 “双大括号”:JSX 中的 CSS 和 对象 | Using “double curlies”: CSS and other objects in JSX

In addition to strings, numbers, and other JavaScript expressions, you can even pass objects in JSX. Objects are also denoted with curly braces, like { name: "Hedy Lamarr", inventions: 5 }. Therefore, to pass a JS object in JSX, you must wrap the object in another pair of curly braces: person={{ name: "Hedy Lamarr", inventions: 5 }}. 除了字符串、数字和其它 JavaScript 表达式,你甚至可以在 JSX 中传递对象。对象也用大括号表示,例如 { name: "Hedy Lamarr", inventions: 5 }。因此,为了能在 JSX 中传递,你必须用另一对额外的大括号包裹对象:person={{ name: "Hedy Lamarr", inventions: 5 }}

You may see this with inline CSS styles in JSX. React does not require you to use inline styles (CSS classes work great for most cases). But when you need an inline style, you pass an object to the style attribute: 你可能在 JSX 的内联 CSS 样式中就已经见过这种写法了。React 不要求你使用内联样式(使用 CSS 类就能满足大部分情况)。但是当你需要内联样式的时候,你可以给 style 属性传递一个对象:

export default function TodoList() {
  return (
    <ul style={{
      backgroundColor: 'black',
      color: 'pink'
    }}>
      <li>Improve the videophone</li>
      <li>Prepare aeronautics lectures</li>
      <li>Work on the alcohol-fuelled engine</li>
    </ul>
  );
}

Try changing the values of backgroundColor and color. 试着更改一下 backgroundColorcolor 的值。

You can really see the JavaScript object inside the curly braces when you write it like this: 当你写成这样时,你可以很清楚地看到大括号里包着的对象:

<ul style={
{
backgroundColor: 'black',
color: 'pink'
}
}>

The next time you see {{ and }} in JSX, know that it’s nothing more than an object inside the JSX curlies! 所以当你下次在 JSX 中看到 {{}}时,就知道它只不过是包在大括号里的一个对象罢了!

陷阱

Inline style properties are written in camelCase. For example, HTML <ul style="background-color: black"> would be written as <ul style={{ backgroundColor: 'black' }}> in your component. 内联 style 属性 使用驼峰命名法编写。例如,HTML <ul style="background-color: black"> 在你的组件里应该写成 <ul style={{ backgroundColor: 'black' }}>

JavaScript 对象和大括号的更多可能 | More fun with JavaScript objects and curly braces

You can move several expressions into one object, and reference them in your JSX inside curly braces: 你可以将多个表达式合并到一个对象中,在 JSX 的大括号内分别使用它们:

const person = {
  name: 'Gregorio Y. Zara',
  theme: {
    backgroundColor: 'black',
    color: 'pink'
  }
};

export default function TodoList() {
  return (
    <div style={person.theme}>
      <h1>{person.name}'s Todos</h1>
      <img
        className="avatar"
        src="https://i.imgur.com/7vQD0fPs.jpg"
        alt="Gregorio Y. Zara"
      />
      <ul>
        <li>Improve the videophone</li>
        <li>Prepare aeronautics lectures</li>
        <li>Work on the alcohol-fuelled engine</li>
      </ul>
    </div>
  );
}

In this example, the person JavaScript object contains a name string and a theme object: 在这个示例中,person JavaScript 对象包含 name 中存储的字符串和 theme 对象:

const person = {
name: 'Gregorio Y. Zara',
theme: {
backgroundColor: 'black',
color: 'pink'
}
};

The component can use these values from person like so: 该组件可以这样使用来自 person 的值:

<div style={person.theme}>
<h1>{person.name}'s Todos</h1>

JSX is very minimal as a templating language because it lets you organize data and logic using JavaScript. JSX 是一种模板语言的最小实现,因为它允许你通过 JavaScript 来组织数据和逻辑。

摘要

Now you know almost everything about JSX: 现在你几乎了解了有关 JSX 的一切:

  • JSX attributes inside quotes are passed as strings.
  • JSX 引号内的值会作为字符串传递给属性。
  • Curly braces let you bring JavaScript logic and variables into your markup.
  • 大括号让你可以将 JavaScript 的逻辑和变量带入到标签中。
  • They work inside the JSX tag content or immediately after = in attributes.
  • 它们会在 JSX 标签中的内容区域或紧随属性的 = 后起作用。
  • {{ and }} is not special syntax: it’s a JavaScript object tucked inside JSX curly braces.
  • {{}} 并不是什么特殊的语法:它只是包在 JSX 大括号内的 JavaScript 对象。

1挑战 3 个挑战:
修复错误 | Fix the mistake

This code crashes with an error saying Objects are not valid as a React child: 这段代码崩溃了,并打印出这样一个错误 Objects are not valid as a React child

const person = {
  name: 'Gregorio Y. Zara',
  theme: {
    backgroundColor: 'black',
    color: 'pink'
  }
};

export default function TodoList() {
  return (
    <div style={person.theme}>
      <h1>{person}'s Todos</h1>
      <img
        className="avatar"
        src="https://i.imgur.com/7vQD0fPs.jpg"
        alt="Gregorio Y. Zara"
      />
      <ul>
        <li>Improve the videophone</li>
        <li>Prepare aeronautics lectures</li>
        <li>Work on the alcohol-fuelled engine</li>
      </ul>
    </div>
  );
}

Can you find the problem? 你能找到问题出在哪吗?