经过上一小节学习,我们已经掌握了通过 React 组件来构建 Web 界面的技巧。React 组件是一种根据指定参数,来渲染某部分前端界面的代码实体,能有效简化代码,并提高代码复用性。
不过还有点美中不足,调用 React 接口创建虚拟 DOM 元素这个操作还是比较繁琐:
|
|
React 虚拟 DOM 元素最终将渲染成真正的浏览器 DOM 结构,比如例子①最终将渲染出 a 标签:
|
|
- 第一个参数为标签名;
- 第二个参数为标签属性;
- 第三个参数为子节点;
Web 界面结构由 HTML 定义,因为这种类 XML 标记语言比较擅长描述 Web 界面。如果 JS 也可以支持 XML 语法,那就太好了!我们就可以在 React 中用 HTML 语法来描述 Web 界面!
|
|
试想如果例子②可以成这样,那是多么简洁!
然而很遗憾,JS 并不支持 HTML 语法。如果我们直接在 JS 中写 HTML 语法,浏览器就会报错……不过,我们也可以用编译器将代码编译成浏览器能够读懂的原生 JS 后,再让浏览器执行。
这就是本节要介绍的主角—— JSX !
JSX
JSX 是 JS 和 Xml 的缩写,顾名思义就是 JS 支持下的 XML 。有了它我们就可以在 JS 里面,用 XML 语法编写前端界面!那么,它又是怎么实现的呢?
JSX 其实是一种语法糖,在浏览器上执行之前,必须先由编译器进行编译。举个例子:
|
|
编译器会将这个 JSX 语法转换成原生的 JS 语法,即 React 虚拟 DOM 元素创建语句:
|
|
由此可见,JSX 也没啥神秘的,本质上也是创建 React 虚拟 DOM 元素。只不过 JSX 语法比原生 JS 更为简洁,XML 结构也更加贴近前端开发人员的思维方式。
注意到,JSX 引用当前变量时需要用花括号,中间可以写任何 JS 表达式。这个例子,花括号中表达式引用 someBooks 变量,表示取当前执行上下文中的 someBooks 变量作为组件的 books 参数。
此外,JSX 既支持原生 HTML 标签,有支持 React 组件。其中,小写字母表示原生标签,大写字母开头的表示 React 组件:
|
|
Babel
那么,我们应该如何编译 JSX 呢?答案是—— Babel !
Babel 是一个 JS 编译器,可以将用新特性写的 JS 代码,编译成旧版 JS 支持的语法。
在前端发展的过程中,浏览器版本始终是一个令人头痛的问题。早年间为了兼容老浏览器,只能用很原始的 JS 语法,新特性不能谁便用,因为老浏览器可能不支持……
这时,Babel 应运而生!有了它,开发人员可以随意使用任何新特性,完全不用担心浏览器兼容性问题。因为 Babel 会对代码进行编译加工,将其转换成浏览器都能支持的语法。
当然了,Babel 也能帮我们转换 JSX ,只需在页面中将它引入:
|
|
现在,我们就可以用 JSX 语法来编写 Web 界面了:
|
|
Babel 会对 type 为 text/babel 所有 script 标签代码进行编译,再给浏览器执行。效果大致如下:
See the Pen for-var by fasionchan (@fasionchan) on CodePen.
看到 JSX 成功在浏览器上渲染出来,是不是很激动呢!
直接在浏览器上用 Babel 编译 JSX 性能较差,请不要在生产应用上使用这种方式!!!
开发实战
现在,我们用 JSX 语法将前面的分类书单应用重构一遍,看能碰撞出什么火花!
我们还是以自底向上的思路,先重构 Book 组件:
JSX 比直接写 React 接口调用清晰多了,代码也简洁很多。跟 HTML 一样,我们一眼就能看出组件由嵌套 img 的 a 标签构成:
- 链接跳转地址取自 book 参数 jingdong_url 属性;
- 封面图片地址取自 book 参数 image_url 属性;
BookList 组件也是类似的,注意到第 13 行通过 JSX 语法引入 Book 子组件:
其他组件这里不再赘述,请自行重构一番练练手。最后附上完整代码和最终效果,以供参考:
See the Pen for-var by fasionchan (@fasionchan) on CodePen.
【小菜学React】系列文章首发于公众号【小菜学编程】,敬请关注: