0%

【React基础-2】JSX

本文是【React基础】系列的第二篇文章,这篇文章中我们介绍一下在react中一种另类的编码方式——JSX。它可是允许我们将HTML标签直接编写在JS代码中的呦,感兴趣的话就一起来学习吧。

概述

上一篇文章在结束时大家肯定会有很多疑问,这篇文章开始我们就为大家开始一一解答这些疑问。本文首先解答一下第一个疑问:为什么在js后缀的代码文件中可以编写HTML标签代码,并且代码还不会报错?

项目demo地址

1
https://github.com/xuqwCloud/reactbasic

JSX简介

JSX并不是一种新的编程语言或者是新的技术,只要你会JS和HTML,那么你就会JSX,因为JSX其实就是JS代码的语法糖而已。

在react中是允许我们将HTML和JS代码混合来编写的,比如你看到的下面这段代码,它是可以成功运行并且有返回值的:

1
2
3
4
import React from 'react';
import ReactDOM from 'react-dom';
let element = <h1>JSX Hello World</h1>;
ReactDOM.render(element, document.getElementById('root'));

上述代码中我们将一段HTML标签代码赋值给了一个element变量,最后将这个变量当做参数传给了React的render()方法,此时在浏览器页面我们可以看到正常的页面显示,如下:

img

如果你之前没有接触过react的话当你第一次看到这段代码会很惊讶,心想:这肯定是写错了啊,这种代码怎么可能会运行。但是在react项目里这种代码到处都是,而且它们都能正常运行,因为这是一种react提供给我们编写代码的语法糖,有了这种编码方式,我们的程序开发效率会大幅度提高,如果你用JSX用的时间久了,我相信你会爱上它。

那为什么react会无缘无故提出来这么一个东西呢?就用传统的HTML文件、JS文件、CSS文件来共同组合开发一个页面不好吗?这是因为react认为我们开发过程中,其实渲染逻辑是和UI逻辑存在着内在的耦合关系的,比如要在某些UI中绑定鼠标点击事件、如果有些数据改变的话需要将新的数据渲染到UI、在UI中展示后台请求返回的数据等等,这些操作其实并不适合在HTML文件中单纯的编写UI,在JS文件中单纯的编写交互逻辑这样传统的开发方式,react直接将传统的开发模式进行了颠覆,它没有让我们开发人员人为的去将HTML、JS、CSS分离开来,而是将HTML和JS共同存放在了一个单元逻辑中,并将这个单元逻辑称之为”组件”。

所以在react开发中,我们其实就是在开发一个个的组件,通过将这些个组件进行不同的组合,来实现一个完整的页面系统。那么你可能会问,我直接将HTML代码和JS代码混合在一起编写,代码执行的时候它是怎样区分的呢?这其实就是React在做的事情,它会将我们编写的JSX代码进行解析,对这个过程有兴趣的小伙伴,可关注博主后期的react源码解读文章,里面会详细介绍,本文大家只需要知道我们在react中编写JSX这种代码是合法的即可。

JSX中的表达式

在编写JSX代码时,我们可以在大括号中放置任何有效的JavaScript表达式,比如下面这些代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import React from 'react';
import ReactDOM from 'react-dom';
// JSX表达式 变量
let name = 'xbeichenbei.com';
// JSX表达式 函数
function getName() {
return 'X北辰北';
}
let element = (
<h1>
{getName()}的网站域名是{name},建站已经{1 + 2}年了!
</h1>
);
ReactDOM.render(element, document.getElementById('root'));

img

JSX中的特定属性

在编写JSX代码时,我们HTML标签元素的属性可以通过引号或者大括号的形式指定,比如下面这样:

1
2
3
4
5
6
7
let classTest = 'view';
let element = (
<h1 id="xbeichenbei" className={classTest}>
指定标签属性
</h1>
);
ReactDOM.render(element, document.getElementById('root'));

img

上述代码中我们为h1元素指定了id和class属性,其中前者属性值是之前我们熟悉的字符串形式,后者的属性值是通过大括号的方式指定的,并且后者class的属性名称我们用了className,并没有使用class,这是因为JSX的编码方式更加接近JS,但是class这些名称在JS中是关键字,所以react在指定元素属性名称的时候使用了小驼峰的形式,并没有使用HTML默认的属性名称,大家在写代码的时候一定要注意。

JSX到底是怎么执行的

在我们react项目应用的底层其实是有将JSX代码转为正常的JS代码的工具的,它的名字叫”Babel”。Babel会把JSX转译成一个名为React.createElement()的函数调用。

所以下面这两种示例代码完全等效:

1
2
3
4
5
6
7
8
9
10
11
12
//JSX形式的代码
const element = (
<h1 className="greeting">
Hello, world!
</h1>
);
//JS形式的代码
const element = React.createElement(
'h1',
{className: 'greeting'},
'Hello, world!'
);

React.createElement()会预先执行一些检查,帮助我们编写没有错误的代码,但实际上它创建了一个这样的对象:

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

这些对象被称为 “React 元素”。它们描述了我们希望在屏幕上看到的内容。React 通过读取这些对象,然后使用它们来构建DOM以及保持随时更新。

其他

在我们上述的代码里面,我们都是将一个HTML标签元素赋值给变量,如果我们将一个包含有子节点的DOM节点赋值给变量的话该怎么操作呢?其实很简单,仅仅需要在赋值的时候用一个括号包裹这段HTML节点即可,如下:

1
2
3
4
5
6
let element = (
<div>
<span>子节点1</span>
<img src="img.png" />
</div>
);

我们编写前端代码的时候,大家在安全方面一定会考虑XSS攻击,但是在react中编写JSX的时候大家不必过多担心,因为JSX编写的组件代码在渲染之前都是经过编译的,所以在我们的应用中永远不会有那些并非自己明确编写的内容。

总结

以上就是关于JSX的简单介绍,其实本文中大家只需要知道JSX方式的代码怎么编写,并且了解大括号的这种写法、元素的属性名称的部分改变即可,其他的不必做更多的关注。