JSX熟习
引子
近来几个月做的一个项目,运用了react手艺系统,自然而然的用到了JSX。下面就总结一下自身对JSX的熟习。
什么是JSX
即JavaScript XML,一种在React组建内部构建标签的类XML语法。(加强React递次组件的可读性)
JSX可以看做JavaScript的拓展,看起来有点像XML。运用React,可以举行JSX语法到JavaScript的转换。
下面我们来看一下一个简朴的例子。
考虑一下这个变量的声明:
const element = <h1>Hello, world!</h1>;
这个标签语法既不是字符串也不是HTML,这就是JSX。它是JavaScript的一种扩大语法。
JSX小例子
我们先从官网的一个最简朴的例子提及,为了让人人可以直接在当地运转,我贴出了完整的代码以下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Hello React!</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react-dom.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.24/browser.min.js"></script>
</head>
<body>
<div id="example"></div>
<script type="text/babel">
const element = <h1>Hello, world!</h1>;
ReactDOM.render(
element,
document.getElementById('example')
);
</script>
</body>
</html>
人人可以直接粘贴上面代码,保存在当地的一个test.html文件里,双击翻开后,在浏览器里输出:
Hello, world!
我们看到
const element = <h1>Hello, world!</h1>;
element变量的声明就是用了JSX语法,HTML言语直接写在JavaScript言语当中,不加任何引号。
注重:
script
标签的type
属性为text/babel
,这是React 独占的 JSX 语法,跟 JavaScript 不兼容。一般在页面中直接运用 JSX 的处所,都要加上type="text/babel"
。一共用了三个库: react.js 、react-dom.js 和 browser.min.js ,它们必需起首加载。个中,react.js 是 React 的中心库,react-dom.js 是供应与 DOM 相干的功用, browser.min.js的作用是将 JSX 语法转为 JavaScript 语法。
js组织dom
比如要建立一个dom超链接:
<a class="link" href="https://github.com/facebook/react">React<a>
我们在原生DOM中,用js组织dom的体式格局是如许的:
var a = document.createElement('a')
a.setAttribute('class', 'link')
a.setAttribute('href', 'https://github.com/facebook/react')
a.appendChild(document.createTextNode('React'))
这个代码应当是人人比较熟习的。当你在写代码的时刻会不会觉得很烦琐呢,我们可以封装一下:
//第一个参数为node名
//第二个参数为一个对象,dom属性与事宜都以键值对的情势誊写
//第三个到第n个为子node,它们将按参数递次涌现,
//在这个例子中只需一个子元素,而且也是文本元素,所以可以直接誊写,不然还得React.createElement一下
var a = React.createElement('a', {
className: 'link',
href: 'https://github.com/facebook/react'
}, 'React')
看完这个代码,是否是觉得一会儿要简约的多。
如今有个编译东西,可以让你用html语法来写React.createElement,布置上线前编译返来。你情愿吗?
不论你的答案是什么,但这就是jsx的一半原形。
来看个直接的对照
前面已回复过,在运用React的时刻,可以不运用JSX,也许如许写:
var child1 = React.createElement('li', null, 'First Text Content');
var child2 = React.createElement('li', null, 'Second Text Content');
var root = React.createElement('ul', { className: 'my-list' }, child1, child2);
运用如许的机制,我们完整可以用JavaScript构建完整的界面DOM树,正如我们可以用JavaScript建立实在DOM。但如许的代码可读性并不好,因而React发清楚明了JSX
,运用我们熟习的HTML语法来建立假造DOM:
var root =(
<ul className="my-list">
<li>First Text Content</li>
<li>Second Text Content</li>
</ul>
);
总结
这两段代码是完整等价的,后者将XML语法直接加入到JavaScript代码中,让你可以高效的经由过程代码而不是模板来定义界面。
以后JSX经由过程翻译器转换到纯JavaScript再由浏览器实行。
注重
在现实开辟中,JSX在产品打包阶段都已编译成纯JavaScript,JSX的语法不会带来任何机能影响。
别的,由于JSX只是一种语法,因而JavaScript的关键字class, for等也不能涌如今XML中,而要如例子中所示,运用className, htmlFor替代,这和原生DOM在JavaScript中的建立也是一致的。
置信人人在看完了上面的这些举例后,心中的疑问自然而然就水到渠成了。
因而,JSX自身并不是什么深邃的手艺,可以说只是一个比较高等但很直观的语法糖。它异常有效,却不是一个必需品,没有JSX的React也可以一般事情:只需你愿意用JavaScript代码去建立这些假造DOM元素。
为何运用JSX
抛出疑问
看了上面的这些简朴的demo,人人肯定会抛出如许的疑问:
为何React官方引荐运用JSX呢?
等等。。。
运用React,不一定非要运用JSX语法,可以运用原生的JS举行开辟。
然则React作者强烈建议我们运用JSX,由于:
JSX在定义相似HTML这类树形构造时,非常的简朴清楚明了。
简明的代码构造更利于开辟和保护。
XML有着开闭标签,在构建庞杂的树形构造时,比函数挪用和对象字面量更易读。
可以说这些你会觉得比较隐约,下面来举几个看得见的例子。
前端界面的最基本功用在于展现数据,为此大多数框架都运用了模板引擎,
在AngularJS中:
<div ng-if="person != null">
Welcome back, <b>{{person.firstName}} {{person.lastName}}</b>!
</div>
<div ng-if="person == null">
Please log in.
</div>
在EmberJS中:
{{#if person}}
Welcome back, <b>{{person.firstName}} {{person.lastName}}</b>!
{{else}}
Please log in.
{{/if}}
总结
模板可以直观的定义UI来展现Model中的数据,你没必要手动的去拼出一个很长的HTML字符串,险些每种框架都有自身的模板引擎。
传统MVC框架强调界面展现逻辑和营业逻辑的星散,因而为了应对庞杂的展现逻辑需求,这些模板引擎险些都不可防止的须要生长成一门自力的言语。
如上面代码所示,每一个框架都有自身的模板言语语法。而这无疑增加了框架的门坎和庞杂度。
运用JSX
正由于如此,React直接摒弃了模板而发清楚明了JSX。看上去很像模板言语,但其本质是经由过程代码来构建界面,这使得我们不再须要控制一门新的言语就可以直观的去定义用户界面:控制了JavaScript就已控制了JSX。
这里无妨再援用之前文章举过的例子,在展现一个列表时,模板言语一般供应名为Repeat的语法,比方在Angular中:
<ul class="unstyled">
<li ng-repeat="todo in todoList.todos">
<input type="checkbox" ng-model="todo.done">
<span class="done-{{todo.done}}">{{todo.text}}</span>
</li>
</ul>
而运用JSX,则代码以下:
var lis = this.todoList.todos.map(function (todo) {
return (
<li>
<input type="checkbox" checked={todo.done}>
<span className={'done-' + todo.done}>{todo.text}</span>
</li>
);
});
var ul = (
<ul class="unstyled">
{lis}
</ul>
);
可以看到,JSX圆满运用了JavaScript自带的语法和特征,我们只需记着HTML只是代码建立DOM的一种语法情势,就很轻易明白JSX。
而这类运用代码构建界面的体式格局,完整消除了营业逻辑和界面元素之间的隔膜,让代码越发直观和易于保护。
JSX的语法
你可以用 花括号 把恣意的 JavaScript 表达式 嵌入到 JSX 中。
比方,2 + 2, user.firstName, 和 formatName(user),这些都是可用的表达式。
function formatName(user) {
return user.firstName + ' ' + user.lastName;
}
const user = {
firstName: 'Harper',
lastName: 'Perez'
};
const element = (
<h1>
Hello, {formatName(user)}!
</h1>
);
ReactDOM.render(
element,
document.getElementById('root')
);
JSX 也是一个表达式
编译以后,JSX 表达式就变成了通例的 JavaScript 对象。
这意味着你可以在 if 语句或许是 for 轮回中运用 JSX,用它给变量赋值,当作参数吸收,或许作为函数的返回值。
function getGreeting(user) {
if (user) {
return <h1>Hello, {formatName(user)}!</h1>;
}
return <h1>Hello, Stranger.</h1>;
}
用 JSX 指定属性值
您可以运用双引号来指定字符串字面量作为属性值:
const element = <div tabIndex="0"></div>;
您也可以用花括号嵌入一个 JavaScript 表达式作为属性值:
const element = <img src={user.avatarUrl}></img>;
注重
在属性中嵌入 JavaScript 表达式时,不要运用引号来包裹大括号。不然,JSX 将该属性视为字符串字面量而不是表达式。
关于字符串值你应当运用引号,关于表达式你应当运用大括号,但二者不能同时用于统一属性。
用 JSX 指定子元素
如果是空标签,您应当像 XML 一样,运用 />马上闭合它:
const element = <img src={user.avatarUrl} />;
JSX 标签可以包括子元素:
const element = (
<div>
<h1>Hello!</h1>
<h2>Good to see you here.</h2>
</div>
);
JSX 防备注入进击
在JSX中嵌入用户输入是平安的:
const title = response.potentiallyMaliciousInput;
// This is safe:
const element = <h1>{title}</h1>;
默许情况下, 在衬着之前, React DOM 会格式化(escapes) JSX中的一切值。
从而保证用户没法注入任何运用以外的代码。
在被衬着之前,一切的数据都被转义成为了字符串处置惩罚。 以防止 XSS(跨站剧本) 进击。
JSX 示意对象
Babel 将JSX编译成 React.createElement() 挪用。
下面的两个例子是是完整相同的:
const element = (
<h1 className="greeting">
Hello, world!
</h1>
);
const element = React.createElement(
'h1',
{className: 'greeting'},
'Hello, world!'
);
React.createElement() 会实行一些搜检来协助你编写没有bug的代码,但基本上它会建立一个以下所示的对象:
// 注重: 这是简化的构造
const element = {
type: 'h1',
props: {
className: 'greeting',
children: 'Hello, world'
}
};
末端
关于JSX的引见也许讲到这里,看完这篇文章后,愿望人人能可以相识什么是JSX,React为何引荐运用JSX等题目。
鄙人一节中来探究如何将 React 元素衬着到 DOM 上。
迎接人人接见我的blog,有更出色的文章吆!
参考链接