1、 扩展语法 JSX

JSX 的全称是 JavaScript XML,它是一种 JavaScript 的语法扩展,允许我们在 JavaScript 中编写类似 HTML 的代码。它的主要作用是让开发者更直观地描述 UI 的结构。

我们可以直接在 JS 代码中,把 JSX 语法当成一种表达式进行运算与赋值。

const element = <h1>Hello, JSX!</h1>

从长相上来说,它跟 html 标签几乎没有差别,但它不是 html。我们可以在 JavaScript 代码中任意拆分组合这些元素。

例如,一段完整的 html 元素如下:

1
<div>
2
<header>header</header>
3
<span>hello world.</span>
4
<footer>footer</footer>
5
</div>

而 JSX 可以这样写

1
const header = <header>header</header>
2
3
const div = (
4
<div>
5
{header}
6
<span>hello world.</span>
7
<footer>footer</footer>
8
</div>
9
)

还可以这样

1
const header = <header>header</header>
2
3
function footer() {
4
return <footer>footer</footer>
5
}
6
7
const div = (
8
<div>
9
{header}
10
<span>hello world.</span>
11
{footer()}
12
</div>
13
)

这样的灵活性,为开发者在拆分逻辑时提供了巨大的想象空间。我们可以抽离任意部分单独处理,也可以将任意部分通过合适的方式组合在一起。

注意:JSX 代码需要在 React 环境之下才有效。并且我们需要将具备 JSX 代码的模块文件以 .jsx 或者 .tsx 为后缀名。

在 JSX 中,开发者可以在大括号中放置任何有效的 JavaScript 表达式。例如

const element = <div>计算结果:{2 + 2}</div>

或者

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

JSX 中的属性(类似于 HTML 的属性)可以是字符串,也可以是 JavaScript 表达式。

1
const url = 'https://example.com';
2
const element = <img src={url} alt="Example" />;

2、 JSX 本质

JSX 本身也是一个表达式,例如可以作为一个函数的返回结果。从视觉上看他是一个标签,但是当我们对其取值时,它本质是一个 JavaScript 对象

在开发环境中,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
);

他们创建了一个这样的对象

1
// 注意:这是简化过的结构
2
const element = {
3
type: 'h1',
4
props: {
5
className: 'greeting',
6
children: 'Hello, world!'
7
}
8
};

标签元素是 React 组件的重要组成部分。

在开发中,我们通常会使用 JSX 的可任意拆分组合的特性,将整个项目拆分成许多模块,并最后组合成一个完整的 JSX,并使用 createRoot 渲染到已经存在的根 DOM 节点中。

1
import React from 'react';
2
import { createRoot } from 'react-dom/client'
3
4
import './index.css';
5
import App from './App';
6
7
8
const root = createRoot(document.getElementById('root'))
9
root.render(<App />)

这些与 html 元素类似的标签元素,被称之为 React 元素。他们是不可变对象。一个元素就像电影中的一帧,它代表了某个特定时刻的 UI。

我们可以利用 React 元素创建自定义组件。

1
function Welcome(props) {
2
return <h1>Hello, {props.name}</h1>;
3
}

每个自定义组件,也可以看成是一个 React 元素。

1
const element = <Welcome name="Tony" />;
2
...
  • 在自定义时,标签元素上所有的属性以及该元素的子组件,都会聚合到 props 中,也就是函数的第一个参数。
  • 自定义组件必须以大写字母开头
  • 注意:自定义组件也可以参与到 JSX 的任意拆分与组合中去。

3、 JSX 的特殊规则

  1. JSX 必须有一个根元素,不能返回多个并列的元素。
1
// bad
2
const element = (
3
<h1>Title</h1>
4
<p>Content</p>
5
);
6
7
// good
8
const element = (
9
<div>
10
<h1>Title</h1>
11
<p>Content</p>
12
</div>
13
);
  1. 使用 className 代替 class. 因为 class 是 JavaScript 的关键字,所以在 JSX 中需要用 className 来代替。
1
// 而不是 class
2
const element = <div className="container">Content</div>;
  1. 使用 htmlFor 代替 for. 同样,for 是 JavaScript 的关键字,所以在 JSX 中需要用 htmlFor 来代替。
1
// for -> htmlFor
2
const element = <label htmlFor="name">Name</label>;
  1. style 属性需要传入对象。如下所示
1
const element = <div
2
style={{ color: 'red', fontSize: '20px' }}
3
>
4
Styled Text
5
</div>;

4、 总结

本文主要内容在于阐述 JSX 语法并明确标签语言的本质,使用时重点要关注其可任意拆分组合的特性。他的灵活性在开发时非常有用。

JSX 最初是专门为 React 设计的,但是发展到现在,其他库也陆续支持了这种表达 UI 的方式,例如 Vue、Solidjs、Preact 等。

专栏首页
到顶
专栏目录