什么是JSX
JSX = Javascript + XML,JSX是一个 JavaScript 的语法扩展。 JSX可以很好地描述 UI 应该呈现出它应有交互的本质形式并且其完全可以和JavaScript融合在一起使用。而且具有 JavaScript 的全部功能。JSX 可以生成 React “元素”。
JSX代码示例:
const element = <h1>Hello, world!</h1>;
为什么使用 JSX?
- React认为渲染逻辑本质上与其他UI逻辑存在内在耦合,而jsx正好符合这种编程逻辑。
- JSX 执行更快,因为它在编译为 JavaScript 代码后进行了优化。
- JSX的类型是安全的,在编译过程中就能发现错误。
- 使用 JSX 编写模板更加简单快速。
- 在 JavaScript 代码中将 JSX 和 UI 放在一起时,会在视觉上有辅助作用。它还可以使 React 显示更多有用的错误和警告消息。
JSX的书写规范
- JSX的顶层只能有一个根元素,所以我们很多时候会在外层包裹一个div原生(或者使用Fragment)。
- 为了方便阅读,我们通常在jsx的外层包裹一个小括号(),这样可以方便阅读,并且jsx可以进行换行书写。
- JSX中的标签可以是单标签,也可以是双标签。
注意: 如果是单标签,必须以/>结尾
在 JSX 中嵌入表达式
在JSX中可以使用大括号 {} 嵌入表达式,而且在 JSX 语法中,你可以在大括号内放置任何有效的JavaScript 表达式,例如运算表达式、三元运算符、执行一个函数。
- 情况一:当变量是Number、String、Array类型时,可以直接显示
- 情况二:当变量是null、undefined、Boolean类型时,内容为空;
- 如果希望可以显示null、undefined、Boolean,那么需要转成字符串;
- 转换的方式有很多,比如toString方法、和空字符串拼接,String(变量)等方式;
- 情况三:对象类型不能作为子元素(not valid as a React child)
JSX代码示例:
function formatName(user) {
return user.firstName + user.lastName;
}
const user = {
firstName: 'za',
lastName: 'yyo',
};
const name ="Hello";
const element = <h1>{name},{formatName(user)}!</h1>;
ReactDOM.render(
element,
document.getElementById('root')
);
JSX 也是一个表达式
在经过babel编译之后,JSX 表达式会被转为普通 JavaScript 函数。并且会编译运行得到最终的表达式结果。
JSX 中可以嵌入
- 运算表达式
- 三元运算符
- 也可以执行一个函数
function getGreeting(user) {
if (user) {
return <h1>Hello, {formatName(user)}!</h1>; }
return <h1>Hello, Stranger.</h1>;}
JSX 可以绑定属性
我们可以使用引号来将属性值指定为字符串字面量,也可以使用大括号,来在属性值中插入一个 JavaScript 表达式。
- 比如元素都会有title属性
- 比如img元素会有src属性
- 比如a元素会有href属性
- 比如元素可能需要绑定class
- 比如原生使用内联样式style
//使用引号将属性值指定为字符串字面量
const element = <div tabIndex="0"></div>;
//使用大括号,来在属性值中插入一个 JavaScript 表达式
const element = <img src={user.avatarUrl}></img>;
注意: 因为 JSX 语法上更接近 JavaScript 而不是 HTML,所以 React DOM 使用 camelCase
(小驼峰命名)来定义属性的名称,而不使用 HTML 属性名称的命名约定。
使用 JSX 指定子元素
当我们的标签里面没有内容时,我们可以采用单标签的形式。组件同理。
const element = <img src={user.avatarUrl} />;
当然JSX里也能有很多标签,只需要把他们音()括起来。
const element = (
<div>
<h1>Hello!</h1>
<h2>Good to see you here.</h2>
</div>
);
JSX可以防止注入攻击
我们可以安全地在 JSX 当中直接插入用户输入内容,因为React DOM 在渲染所有输入内容之前,默认会进行转义。它可以确保在你的应用中,永远不会注入那些并非自己明确编写的内容。所有的内容在渲染之前都被转换成了字符串。这样可以有效地防止 XSS(cross-site-scripting, 跨站脚本)攻击。
const title = 用户输入的内容,或者请求的连接
// 直接使用是安全的:
const element = <h1>{title}</h1>;
JSX 表示对象
实际上,jsx 仅仅只是 React.createElement(component, props, …children) 函数的语法糖。
所有的jsx最终都会被转换成React.createElement的函数调用
const element = (
<h1 className="greeting">
Hello, world!
</h1>
);
我们编写的代码最终会被转化为React.createElement的函数调用
createElement需要传递三个参数:
参数一:type
- 当前ReactElement的类型;
- 如果是标签元素,那么就使用字符串表示 “div”;
- 如果是组件元素,那么就直接使用组件的名称;
参数二:config
- 所有jsx中的属性都在config中以对象的属性和值的形式存储
参数三:children
- 存放在标签中的内容,以children数组的方式进行存储;
- 当然,如果是多个元素呢?React内部有对它们进行处理,
// 注意:这是简化过的结构
const element = {
type: 'h1',
props: {
className: 'greeting',
children: 'Hello, world!'
}
};
这种对象被称为 “React 元素”。它们描述了你希望在屏幕上看到的内容。React 通过读取这些对象,然后使用它们来构建 DOM 以及保持随时更新。
我们知道默认jsx是通过babel帮我们进行语法转换的,所以我们之前写的jsx代码都需要依赖babel。
可以在babel的官网中快速查看转换的过程:babeljs.io/repl/#?pres…
虚拟DOM(Virtual DOM)
这个ReactElement对象是什么作用呢?React为什么要创建它呢?
- 原因是React利用ReactElement对象组成了一个JavaScript的对象树;
- JavaScript的对象树就是大名鼎鼎的虚拟DOM(Virtual DOM);
如何查看ReactElement的树结构呢?
我们可以将之前的jsx返回结果进行打印。注意下面代码中我打jsx的打印
ReactElement最终形成的树结构就是Virtual DOM;
为什么使用虚拟DOM?
为什么要采用虚拟DOM,而不是直接修改真实的DOM呢?
-
很难跟踪状态发生的改变:原有的开发模式,我们很难跟踪到状态发生的改变,不方便针对我们应用程序进行调试;
-
操作真实DOM性能较低:传统的开发模式会进行频繁的DOM操作,而这一的做法性能非常的低;
-
首先,document.createElement本身创建出来的就是一个非常复杂的对象;
-
其次,DOM操作会引起浏览器的回流和重绘,所以在开发中应该避免频繁的DOM操作;
-
-
虚拟DOM帮助我们从命令式编程转到了声明式编程的模式。使得编写效率更高
- 你只需要告诉React希望让UI是什么状态,React来确保DOM和这些状态是匹配的,你不需要直接进行DOM操作,只可以从手动更改DOM、属性操作、事件处理中解放出来
写在最后
伙伴们,如果你觉得我写的文章对你有帮助就给zayyo点一个赞👍或者关注➕都是对我最大的支持。当然你也可以加我微信:IsZhangjianhao,邀你进我的前端学习交流群,一起学习前端,成为更优秀的工程师~
原文链接:https://juejin.cn/post/7228100170797662264 作者:zayyo