什么是 JSX
- JSX 是一种JavaScript 的语法扩展,是嵌入到 JavaScript 中的一种语法结构,也有很多地方称之为JavaScript XML, 因为看起来是一段 XML 语法。
- 它用于描述我们的 UI界面,并且其完全可以和 JavaScript 融合在一起使用;
- 它是为了方便创建虚拟 DOM 的。
为什么React 选择 JSX
- React 认为渲染逻辑本质上与其他 UI逻辑存在内在耦合
- 比如 UI 需要绑定事件(button、a 等等)
- 比如 UI中需要展示数据状态,在某些状态发生改变时,又需要改变 UI
- 他们之间是密不可分的,所以 React 没有将标记分离到不同的文件中,而是将他们组合到了一起,这就是组件。
JSX 语法规则
- JSX 的顶层只能由一个根元素,所以很多时候会在外层包裹一个 div 或 Fragment
- jsx 中的标签可以是双标签,也可以是单标签,但是如果是单标签需要注意必须是自闭和标签必须以/>结尾,例如
<input type = "text"/>
- 创建虚拟 DOM 时,不要写引号
const VDOM = <h1>Hello React</h1>
- 标签中不要混入js 表达式,要使用{JS 表达式},
const data = 'Hello React'; const VDOM = <h1>{data}<h1>
- 标签中样式的类名要用className 指定
const VDOM = <h1 className='title'>{data}<h1>
- 标签中的内联样式要用
style={{color:'white',fontSize:'60px'}}
,注意属性名转为小驼峰const VDOM = <h1 style={{color:'white',fontSize:'60px'}} className='title'>{data}<h1>
- 关于标签首字母: 1.若首字母小写,那么 React 就会去寻找与之同名的 html 标签,若找见,直接转为 html 同名元素,若未找见,报错,2.若首字母大写,那么 React 就会去寻找与之同名的组件,若找见,那么就使用组件,若未找见,报错
JSX 使用
- jsx 中的注释需要使用大括号{} 括起来,然后用使用/**/注释
<div>"开始"</div>
{/* <div>"内容"</div> */}
<div>"结束"</div>
- 使用 jsx,并且希望 script 中的 jsx代码被解析,必须在 script 标签中添加一个属性type="text/babel"
<script type="text/babel"> </script>
- 为了方便书写,通常在 jsx 的外层包裹一个小括号,这样方便阅读,并且 jsx 可以进行换行书写
jsx 中嵌入变量
- 当变量是 Number、String、Array 类型时,可以直接显示
- 当变量是 null、undefined、Boolean 类型时,内容为空
- 如果希望可以显示null、undefined、Boolean,需要转换成字符串, 比如 toString(), String(null)等方式
- 对象类型不能作为子元素,会报
not valid as a React child
jsx 中嵌入表达式
- 可以嵌入运算表达式
- 可以嵌入三元运算
- 可以执行一个函数
JSX 的本质
- 实际上 jsx 仅仅是 React.creatElement(component,props,...children)函数的语法糖,所有的 jsx 最终都会被转换成React.creatElement的函数调用
- React.creatElement 函数
- 该函数需要传递三个参数
- 参数一: type
- 当前 ReactElement 的类型, 如果是标签元素,那么使用字符串表示,比如'div', 如果是组件元素,那就直接使用组件名称,比如:
const message2 = React.createElement("h2", null, "Hello React");
- 参数二: config
- 所有 jsx 中的属性都在 config 中以对象的属性和值的形式存储
- 参数三:children
- 存放在标签中的内容,以 children 数组的方式进行存储
注意
: 这里虽然只有三个参数,但是却可以传很多个参数,那么它是怎么接收的呢? 前两个参数是对应死的,如果参数是三个,那么带三个参数就是给 children 的,如果大于三个,会从函数当前的总参数数组中把前两个参数过滤掉,然后剩下的再一一取出
- 我们可以利用babel 官网的 try it out将我们写的 jsx 换换成React.createElement函数参看,如下我们的转换
<div>
<div className="header">
<h1 title="标题">我是标题</h1>
</div>
<div className="content">
<h2>我是页面的内容</h2>
<button>按钮</button>
<button>+1</button>
<a href="http://www.baidu.com">百度一下</a>
</div>
<div className="footer">
<p>我是尾部的内容</p>
</div>
</div>
// 转换后如下:
"use strict";
/*#__PURE__*/
React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
className: "header"
}, /*#__PURE__*/React.createElement("h1", {
title: "\u6807\u9898"
}, "\u6211\u662F\u6807\u9898")), /*#__PURE__*/React.createElement("div", {
className: "content"
}, /*#__PURE__*/React.createElement("h2", null, "\u6211\u662F\u9875\u9762\u7684\u5185\u5BB9"), /*#__PURE__*/React.createElement("button", null, "\u6309\u94AE"), /*#__PURE__*/React.createElement("button", null, "+1"), /*#__PURE__*/React.createElement("a", {
href: "http://www.baidu.com"
}, "\u767E\u5EA6\u4E00\u4E0B")), /*#__PURE__*/React.createElement("div", {
className: "footer"
}, /*#__PURE__*/React.createElement("p", null, "\u6211\u662F\u5C3E\u90E8\u7684\u5185\u5BB9")));
- 如果我们直接编写 React.createElement代码,那么我们就可以将 script 中的 type="text/babel"删掉了, babel 的引入也可以删掉了, 因为我们没有用 jsx了,没有将 jsx 装换成 React.createElement 的需要了
网友评论