React中JSX的理解
React中JSX的理解
JSX
是快速生成react
元素的一种语法,实际是React.createElement(component, props, ...children)
的语法糖,同时JSX
也是Js
的语法扩展,包含所有Js
功能。
描述
JSX发展过程
在之前,Facebook
是PHP
大户,所以React
最开始的灵感就来自于PHP
。
在2004
年这个时候,大家都还在用PHP
的字符串拼接来开发网站。
$str = "<ul>";
foreach ($talks as $talk) {$str += "<li>" . $talk->name . "</li>";
}
$str += "</ul>";
这种方式代码写出来不好看不说,还容易造成XSS
等安全问题。应对方法是对用户的任何输入都进行转义Escape
,但是如果对字符串进行多次转义,那么反转义的次数也必须是相同的,否则会无法得到原内容,如果又不小心把HTML
标签给转义了,那么HTML
标签会直接显示给用户,从而导致很差的用户体验。
到了2010
年,为了更加高效的编码,同时也避免转义HTML
标签的错误,Facebook
开发了XHP
。XHP
是对PHP
的语法拓展,它允许开发者直接在PHP
中使用HTML
标签,而不再使用字符串。
$content = <ul />;
foreach ($talks as $talk) {$content->appendChild(<li>{$talk->name}</li>);
}
这样的话,所有HTML
标签都使用不同于PHP
的语法,我们可以轻易的分辨哪些需要转义哪些不需要转义。不久的后来,Facebook
的工程师又发现他们还可以创建自定义标签,而且通过组合自定义标签有助于构建大型应用。
到了2013
年,前端工程师Jordan Walke
向他的经理提出了一个大胆的想法:把XHP
的拓展功能迁移到Js
中,首要任务是需要一个拓展来让Js
支持XML
语法,该拓展称为JSX
。因为当时由于Node.js
在Facebook
已经有很多实践,所以很快就实现了JSX
。
const content = (<TalkList>{talks.map(talk => <Talk talk={talk} />)}</TalkList>
);
为何使用JSX
React
认为渲染逻辑本质上与其他UI
逻辑内在耦合,比如在UI
中需要绑定处理事件、在某些时刻状态发生变化时需要通知到UI
,以及需要在UI
中展示准备好的数据。
React
并没有采用将标记与逻辑进行分离到不同文件这种人为地分离方式,而是通过将二者共同存放在称之为组件的松散耦合单元之中,来实现关注点分离。
React
不强制要求使用JSX
,但是大多数人发现,在JavaScript
代码中将JSX
和UI
放在一起时,会在视觉上有辅助作用,它还可以使React
显示更多有用的错误和警告消息。
简单来说,JSX
可以很好的描述页面html
结构,很方便的在Js
中写html
代码,并具有Js
的全部功能。
优点
JSX
的优点主要体现在以下三点:
- 快速,
JSX
执行更快,因为它在编译为JavaScript
代码后进行了优化。 - 安全,与
JavaScript
相比,JSX
是静态类型的,大多是类型安全的。使用JSX
进行开发时,应用程序的质量会变得更高,因为在编译过程中会发现许多错误,它也提供编译器级别的调试功能。 - 简单,语法简洁,上手容易。
JSX实例
规则定义
JSX
中定义了一些规则以及用法:
JSX
只能有一个根元素,JSX
标签必须是闭合的,如果没有内容可以写成自闭和的形式<div />
。- 可以在
JSX
通过{}
嵌入Js
表达式。 JSX
会被babel
转换成React.createElement
的函数调用,调用后会创建一个描述HTML
信息的Js
对象。JSX
中的子元素可以为字符串字面量。JSX
中的子元素可以为JSX
元素。JSX
中的子元素可以为存储在数组中的一组元素。JSX
中的子元素可以为Js
表达式,可与其他类型子元素混用;可用于展示任意长度的列表。JSX
中的子元素可以为函数及函数调用。JSX
中的子元素如果为boolean/null/undefined
将会被忽略,如果使用&&
运算符,需要确保前面的是布尔值,如果是0/1
则会被渲染出来。- 在对象属性中定义
React
组件,可以使用object
的点语法使用该组件。 React
元素会被转换为调用React.createElement
函数,参数是组件,因此React
和该组件必须在作用域内。React
元素需要大写字母开头,或者将元素赋值给大小字母开头的变量,小写字母将被认为是HTML
标签。- 不能使用表达式作为
React
元素类型,需要先将其赋值给大写字母开头的变量,再把该变量作为组件。
JSX的使用
在示例中我们声明了一个名为name
的变量,然后在JSX
中使用它,并将它包裹在大括号中。在JSX
语法中,可以在大括号内放置任何有效的JavaScript
表达式。例如2 + 2
、user.firstName
或formatName(user)
都是有效的JavaScript
表达式。
const name = "Josh Perez";
const element = <h1>Hello, {name}</h1>;ReactDOM.render(element,document.getElementById("root")
);
同样JSX
也是一个表达式,JSX
天生就是需要被编译之后才可以使用的,在编译之后JSX
表达式会被转为普通JavaScript
函数调用,并且对其取值后得到JavaScript
对象。也就是说,你可以在if
语句和for
循环的代码块中使用JSX
,将JSX
赋值给变量,把JSX
当作参数传入,以及从函数中返回JSX
。
function getGreeting(user) {if (user) {return <h1>Hello, {formatName(user)}!</h1>;}return <h1>Hello, Stranger.</h1>;
}
通常可以通过使用引号来将属性值指定为字符串字面量,也可以使用大括号来在属性值中插入一个JavaScript
表达式,在属性中嵌入JavaScript
表达式时,不要在大括号外面加上引号。因为JSX
语法上更接近JavaScript
而不是HTML
,所以React DOM
使用camelCase
小驼峰命名来定义属性的名称,而不使用HTML
属性名称的命名约定。例如JSX
里的class
变成了className
,而tabindex
则变为tabIndex
。
const element1 = <div tabIndex="0"></div>;
const element2 = <img src={user.avatarUrl}></img>;
JSX
中也可以使用</>
来闭合标签,另外JSX
同样也可以直接定义很多子元素。
const element1 = <img src={user.avatarUrl} />;
const element2 = (<div><h1>Hello!</h1><h2>Good to see you here.</h2></div>
);
你可以安全地在JSX
当中插入用户输入内容,React DOM
在渲染所有输入内容之前,默认会进行转义,这样可以确保在你的应用中,永远不会注入那些并非自己明确编写的内容,所有的内容在渲染之前都被转换成了字符串,可以有效地防止 XSS
跨站脚本攻击。
const title = response.potentiallyMaliciousInput;
// 直接使用是安全的:
const element = <h1>{title}</h1>;
实际上Babel
会把JSX
转译成一个名为React.createElement()
函数调用,通过React.createElement()
定义的元素与使用JSX
生成的元素相同,同样这就使得JSX
天生就是需要编译的。
const element1 = (<h1 className="greeting">Hello, world!</h1>
);
// 等价
const element2 = React.createElement('h1',{className: 'greeting'},'Hello, world!'
);
React.createElement()
会预先执行一些检查,以帮助你编写无错代码,但实际上它创建了一个这样的对象。这些对象被称为React 元素
,它们描述了你希望在屏幕上看到的内容,React
通过读取这些对象,然后使用它们来构建DOM
以及保持随时更新。
// 注意:这是简化过的结构
const element = {type: 'h1',props: {className: 'greeting',children: 'Hello, world!'}
};
实际上,这就是虚拟DOM
的一个节点,Virtual DOM
是一种编程概念,在这个概念里,UI
以一种理想化的,或者说虚拟的表现形式被保存于内存中,并通过如ReactDOM
等类库使之与真实的DOM
同步,这一过程叫做协调。这种方式赋予了React
声明式的API
,您告诉React
希望让UI
是什么状态,React
就确保DOM
匹配该状态,这样可以从属性操作、事件处理和手动DOM
更新这些在构建应用程序时必要的操作中解放出来。
与其将Virtual DOM
视为一种技术,不如说它是一种模式,人们提到它时经常是要表达不同的东西。在React
的世界里,术语Virtual DOM
通常与React
元素关联在一起,因为它们都是代表了用户界面的对象,而React
也使用一个名为fibers
的内部对象来存放组件树的附加信息,上述二者也被认为是React
中Virtual DOM
实现的一部分,Virtual DOM
也为使用diff
算法奠定了基础。
<div class="root" name="root"><p>1</p><div>11</div>
</div>
// 使用Js对象去描述上述节点以及文档
{type: "tag",tagName: "div",attr: {className: "root"name: "root"},parent: null,children: [{type: "tag",tagName: "p",attr: {},parent: {} /* 父节点的引用 */, children: [{type: "text",tagName: "text",parent: {} /* 父节点的引用 */, content: "1"}]},{type: "tag",tagName: "div",attr: {},parent: {} /* 父节点的引用 */, children: [{type: "text",tagName: "text",parent: {} /* 父节点的引用 */, content: "11"}]}]
}
示例
<!DOCTYPE html>
<html><head><meta charset="UTF-8" /><title>JSX示例</title>
</head><body><div id="root"></div>
</body>
<script src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">class Clock extends React.Component {constructor(props) {super(props);this.state = { date: new Date() };}componentDidMount() {this.timer = setInterval(() => this.tick(), 1000);}componentWillUnmount() {clearInterval(this.timer);}tick() {this.setState({ date: new Date() });}render() {return (<div><h1>{this.props.tips}</h1><h2>Now: {this.state.date.toLocaleTimeString()}</h2></div>);}}class App extends React.Component{constructor(props){super(props);this.state = { showClock: true,tips: "Hello World!"}}updateTips() {this.setState((state, props) => ({tips: "React update"}));}changeDisplayClock() {this.setState((state, props) => ({showClock: !this.state.showClock}));}render() {return (<div>{this.state.showClock && <Clock tips={this.state.tips} />}<button onClick={() => this.updateTips()}>更新tips</button><button onClick={() => this.changeDisplayClock()}>改变显隐</button></div>);}}var vm = ReactDOM.render(<App />,document.getElementById("root"));
</script></html>
每日一题
https://github.com/WindrunnerMax/EveryDay
参考
https://www.zhihu.com/question/265784392
https://juejin.cn/post/6844904127013584904
https://zh-hans.reactjs.org/docs/introducing-jsx.html
React中JSX的理解相关推荐
- React中refs的理解
React中refs的理解 Refs提供了一种方式,允许我们访问DOM节点或在render方法中创建的React元素. 描述 在典型的React数据流中,props是父组件与子组件交互的唯一方式,要修 ...
- react中jsx行内样式(style)的国定写法、jsx双花括号{{}}写法的解释
共index.js.index.html. TodoList.js这三个文件,主要看TodoList.js中的Input标签的style样式双花括号{{}}的写法,会在下方做全面的解释 运行效果: i ...
- React中JSX的用法和理解
文章目录 React的特点 相关js库 虚拟DOM JSX(JavaScript XML) 使用jsx创建虚拟DOM 使用js创建虚拟DOM 区分js语句(代码)与js表达式 类 事件处理 高阶函数和 ...
- react中 JSX介绍-基本使用
JSX是什么 JSX:是 JavaScript XML的缩写. 在 JS 代码中书写 XML 结构 注意:JSX 不是标准的 JS 语法,是 JS 的语法扩展.脚手架中内置了 @babel/plugi ...
- 歌谣学前端之React中jsx
前言 我是歌谣 我有个兄弟 巅峰的时候排名c站总榜19 叫前端小歌谣 曾经我花了三年的时间创作了他 现在我要用五年的时间超越他 今天又是接近兄弟的一天人生难免坎坷 大不了从头再来 歌谣的意志是永恒的 ...
- React中JSX背后的故事
文章目录 1. JSX的本质: React.createElement这个 JavaScript 调用的语法糖 2. 为什么要用 JSX: 在降低学习成本的同时,也提升了研发效率与研发体验 3. JS ...
- React中jsx的规则
jsx语法规则:1.定义虚拟DOM时,不要写引号.2.标签中混入JS表达式时要用{}.3.样式的类名指定不要用class,要用className.4.内联样式,要用style={{key:value} ...
- 歌谣学前端之React中jsx注意事项
前言 我是歌谣 我有个兄弟 巅峰的时候排名c站总榜19 叫前端小歌谣 曾经我花了三年的时间创作了他 现在我要用五年的时间超越他 今天又是接近兄弟的一天人生难免坎坷 大不了从头再来 歌谣的意志是永恒的 ...
- react 中 JSX 语法的转化过程
JSX 语法的转化过程 JSX 仅仅是 createElement() 方法的语法糖(简化语法) JSX 语法被 @babel/preset-react插件 编译为 createElement() 方 ...
最新文章
- arcgis python编程案例-面向ArcGIS的Python脚本编程
- java 反射 单列_轻松掌握Java单例模式
- 【opencv学习】【hough圆检测】
- asp.net控件全部清空、全部启用、全部禁用方法
- 12.GitLab System Hooks
- What is the Actual Performance of HANA?
- QT高级编程技巧(一)-- 编写高效的signal slot通信代码
- STC单片机程序下载原理与自动下载
- md4c语言_C语言开发世嘉MD游戏【二】:Hello World
- 怎么接微信公众号人工服务器,怎么设置微信公众号接入人工客服?
- CPU 工作原理(附详细图解)
- 大咖直播 | 大连理工赵纪军教授:人工智能算法用于团簇研究和势函数拟合
- idea报错cannot access com.*.*
- 菜鸟学院~全球首个活体机器人诞生:可编程,会自愈,由超级计算机设计
- matlab 矩阵分解行满秩,matlab生成满秩矩阵
- 小菜openstack nova 源码学习之 evacuate
- Jenkins测试报告邮件通知模板(转载)
- JSP常用内置对象及抽奖功能
- Fedora 34 dnf 安装nvidia显卡驱动,支持rtx 2060 ,解决nouveau崩溃故障
- 企业信息化思考 - 如何确保信息化项目落地