React快速入门:使用JSX编写Web界面

经过上一小节学习,我们已经掌握了通过 React 组件来构建 Web 界面的技巧。React 组件是一种根据指定参数,来渲染某部分前端界面的代码实体,能有效简化代码,并提高代码复用性。

不过还有点美中不足,调用 React 接口创建虚拟 DOM 元素这个操作还是比较繁琐:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
// 例子①
// 创建虚拟DOM元素,渲染a标签
React.createElement(
  'a',
  {
    href: "https://fasionchan.com",
  },
  "小菜学编程"
);

// 例子②
// 创建虚拟DOM元素,渲染Book组件
React.createElement(
  Book,
  {
    book: xxxx,
  },
);

React 虚拟 DOM 元素最终将渲染成真正的浏览器 DOM 结构,比如例子①最终将渲染出 a 标签:

1
<a href="https://fasionchan.com">小菜学编程</a>
  • 第一个参数为标签名;
  • 第二个参数为标签属性;
  • 第三个参数为子节点;

Web 界面结构由 HTML 定义,因为这种类 XML 标记语言比较擅长描述 Web 界面。如果 JS 也可以支持 XML 语法,那就太好了!我们就可以在 React 中用 HTML 语法来描述 Web 界面!

1
<Book book={xxxx} />

试想如果例子②可以成这样,那是多么简洁!

然而很遗憾,JS 并不支持 HTML 语法。如果我们直接在 JS 中写 HTML 语法,浏览器就会报错……不过,我们也可以用编译器将代码编译成浏览器能够读懂的原生 JS 后,再让浏览器执行。

这就是本节要介绍的主角—— JSX

JSX

JSXJSXml 的缩写,顾名思义就是 JS 支持下的 XML 。有了它我们就可以在 JS 里面,用 XML 语法编写前端界面!那么,它又是怎么实现的呢?

JSX 其实是一种语法糖,在浏览器上执行之前,必须先由编译器进行编译。举个例子:

1
<BookList books={someBooks} />

编译器会将这个 JSX 语法转换成原生的 JS 语法,即 React 虚拟 DOM 元素创建语句:

1
2
3
4
5
6
React.createElement(
  BookList,
  {
  	books: someBooks,
  },
)

由此可见,JSX 也没啥神秘的,本质上也是创建 React 虚拟 DOM 元素。只不过 JSX 语法比原生 JS 更为简洁,XML 结构也更加贴近前端开发人员的思维方式。

注意到,JSX 引用当前变量时需要用花括号,中间可以写任何 JS 表达式。这个例子,花括号中表达式引用 someBooks 变量,表示取当前执行上下文中的 someBooks 变量作为组件的 books 参数。

此外,JSX 既支持原生 HTML 标签,有支持 React 组件。其中,小写字母表示原生标签,大写字母开头的表示 React 组件:

1
2
3
4
5
// 原生标签
<a href="https://fasionchan.com">小菜学编程</a>

// React组件
<BookList books={someBooks} />

Babel

那么,我们应该如何编译 JSX 呢?答案是—— Babel

Babel 是一个 JS 编译器,可以将用新特性写的 JS 代码,编译成旧版 JS 支持的语法。

在前端发展的过程中,浏览器版本始终是一个令人头痛的问题。早年间为了兼容老浏览器,只能用很原始的 JS 语法,新特性不能谁便用,因为老浏览器可能不支持……

这时,Babel 应运而生!有了它,开发人员可以随意使用任何新特性,完全不用担心浏览器兼容性问题。因为 Babel 会对代码进行编译加工,将其转换成浏览器都能支持的语法。

当然了,Babel 也能帮我们转换 JSX ,只需在页面中将它引入:

1
2
3
<script src="https://unpkg.com/react@18.2.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18.2.0/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone@7.18.12/babel.min.js"></script>

现在,我们就可以用 JSX 语法来编写 Web 界面了:

1
2
3
4
5
6
<script type="text/babel">
  const element = <a href="https://fasionchan.com">小菜学编程</a>;
  const container = document.querySelector('#root');
  const root = ReactDOM.createRoot(container);
  root.render(element);
</script>

Babel 会对 typetext/babel 所有 script 标签代码进行编译,再给浏览器执行。效果大致如下:

See the Pen for-var by fasionchan (@fasionchan) on CodePen.

看到 JSX 成功在浏览器上渲染出来,是不是很激动呢!

直接在浏览器上用 Babel 编译 JSX 性能较差,请不要在生产应用上使用这种方式!!!

开发实战

现在,我们用 JSX 语法将前面的分类书单应用重构一遍,看能碰撞出什么火花!

我们还是以自底向上的思路,先重构 Book 组件:

JSX 比直接写 React 接口调用清晰多了,代码也简洁很多。跟 HTML 一样,我们一眼就能看出组件由嵌套 imga 标签构成:

  • 链接跳转地址取自 book 参数 jingdong_url 属性;
  • 封面图片地址取自 book 参数 image_url 属性;

BookList 组件也是类似的,注意到第 13 行通过 JSX 语法引入 Book 子组件:

其他组件这里不再赘述,请自行重构一番练练手。最后附上完整代码和最终效果,以供参考:

See the Pen for-var by fasionchan (@fasionchan) on CodePen.

小菜学React】系列文章首发于公众号【小菜学编程】,敬请关注:

【小菜学React】系列文章首发于公众号【小菜学编程】,敬请关注: