JSX 即 JavaScript XML, 是Facebook 团队提出的一种在react组件内部构建标签的类XML 语法。可以在 JavaScript 的代码直接中使用 HTML 标签来编写 JavaScript 对象。这种语法方案需要编译转换成真实可用的 JavaScript 代码。 react在不使用JSX的情况下一样可以工作,但是Facebook团队推荐在react使用JSX语法,那么JSX 到底有哪些优势呢?
一、使用JSX的优势
1、更加语义化
在react中,我们可以利用 JavaScript 的语法来书写 html 标签,并且还可以定义自己的组件,这些组件可以根据应用场景,使用更加语义化、更加有意义的标签。这样我们就避开了复杂了JavaScript逻辑,虽然最后都会转换为JavaScript,但是只要熟悉html的设计师以及测试产品的质量保证的人员,都能轻松的阅读组件代码。
2、更加直观
在react中,我们可以将代码分成一个一个组件,每一个组件负责一个功能。通过对各种组件的组合引用,可以构成一个大项目。
例如我们需要创建一个Divider 组件。我们注意到在函数作用域内,使用JSX 语法的版本与使用原生JavaScript 相比,其标签的意图变得更加直观,可读性也更高。
以下是原生JavaScript版本:
// v0.11
render: function () {
return React.DOM.div({className:"divider"},
"Label Text",
React. DOM.hr()
);
}
以下是使用JSX的版本:
render: function () {
return <div className="divider">
Label Text<hr />
</div>;
}
通过对比,我们能发现JSX更直观,也更易懂。
组件化
组件化,也是react的核心,旨在将HTML 标签以及生成这些标签的代码内在地紧密联系在一起,封装成组件,把所有的逻辑和标签封装在其中。与之前的将html、 css 和JavaScript分离不同的是,在 react 中,将以组件和单位,所有的html 、css 和JavaScript都封装在组件中。刚开始,可能会觉得比较别扭,但是当你真正熟悉了JSX 之后,会觉得 JSX 不仅提供了一个清晰、直观的方式来描述组件树,同时还让你的应用程序更加符合逻辑。
JSX 不仅具有这么多优势,而且上手也非常快。下面就具体介绍一下 JSX 的语法使用。
二、JSX语法
JSX 的基本语法规则:遇到 HTML 标签(以 < 开头),就用 HTML 规则解析;遇到代码块(以 { 开头),就用 JavaScript 规则解析。JSX 允许直接在模板插入 JavaScript 变量。
1、封装自己的组件
var HelloMessage = React.createClass({
render: function() {
return <h1>Hello World!</h1>;
}
});
上面我们封装一个输出 “Hello World!” 的组件,组件名为 HelloMessage。
上述代码中,我们可以封装多个 html 标签,但是当有多个标签时,需要将他们封装在一个标签下,也就是说,最终暴露在外面的最外层是一个标签。如下:
var HelloMessage = React.createClass({
render: function() {
return (<div>
<h1>Hello World!</h1>
<p data-myattribute = "somevalue">welcome to my blog...</p>
</div>
);
}
});
如果我们需要给 HTML 标签 添加了自定义属性,添加自定义属性需要使用 data- 前缀。在上述代码中,我们给 p 标签添加了data-myattribute。
另外需要注意的一点是:在 JSX 中,所有的 HTML 标签 和 自定义的组件 在使用时, 都需要闭合。
2、JavaScript 表达式
用{}包起来的语句会当做JavaScript来解析,加引号就会被当成字符串。
var HelloMessage = React.createClass({
render: function() {
return <h1>Hello World!{1+2}</h1>;
}
});
当碰到{1+2}时,会解析成JavaScript语句,并运行得到结果3,因此最终的组件显示内容为Hello World!3
。
在标签属性中也能使用JavaScript表达式,例如:
var HelloMessage = React.createClass({
render: function() {
return <h1 className={ 2>1 ? 'classA' : 'classB'}>Hello World!{1+2}</h1>;
}
});
上述代码中,通过条件判断来设置h1的样式,2>1
为 true , 因此h1的样式为classA。 这里需要说明的是:在JSX中,设置元素的类名时, 不是用 class , 而是用 className。
3、样式
React 推荐使用内联样式。我们可以使用 camelCase (驼峰法)语法来设置内联样式。React 会在指定元素数字后自动添加 px 。以下实例演示了为 h1 元素添加 myStyle 内联样式:
var HelloMessage = React.createClass({
render: function() {
var myStyle = {
color:'red',
fontSize:16
};
return <h1 style={myStyle} >Hello World!{1+2}</h1>;
}
});
我们也可以不定义 myStyle 变量,直接在标签的 style 里写样式,如下:
var HelloMessage = React.createClass({
render: function() {
return <h1 style={{color:'red',fontSize:16}} >Hello World!{1+2}</h1>;
}
});
这两者显示的效果是一样的。
4、数组
JSX 允许在模板中插入数组,数组会自动展开所有成员:
<body>
<div id="example"></div>
<script type="text/babel">
var arr = [
<h1>hello</h1>,
<h2>welcome to my blog....</h2>,
];
ReactDOM.render(
<div>{arr}</div>,
document.getElementById('example')
);
</script>
</body>
效果如下:
如果需要对数组进行遍历,则可以用map,如下:
var arr = ['sean','Lilei','Tom'];
ReactDOM.render(
<div>
{
arr.map(function(elem, index) {
return <h3 key={index}>Hello, {elem}</h3>;
})
}
</div>,
document.getElementById('example')
);
如果数组内是对象,同样可以遍历,然后选择所需的对象属性:
var arr = [{'name':'sean'}, {'name':'Lilei'}, {'name':'Tom'}];
ReactDOM.render(
<div>
{
arr.map(function (elem, index) {
return <h3 key={index}>Hello, {elem.name}</h3>;
})
}
</div>,
document.getElementById('example')
);
注意:上面的两个代码中,在对数组遍历时,都设置了 key 属性,这是因为如果没有设置key 属性时,会出现以下warning:react.js:19287 Warning: Each child in an array or iterator should have a unique "key" prop. Check the top-level render call using <div>. See https://fb.me/react-warning-keys for more information.
。
5、属性 key
key 是JSX 中特有的属性,只在JSX 中存在,而非 DOM 属性。
key 是一个可选的唯一标识符。在程序运行的过程中, 一个组件可能会在组件树中调整位置,比如当用户在进行搜索操作时,或者当一个列表中的物品被增加、删除时。当这些情况发生肘,组件可能并不需要被销毁并重新创建。
通过给组件设置一个独一无二的键,并确保它在一个渲染周期中保持一致,使得React 能够更智能地决定应该重用一个组件,还是销毁并重新创建一个组件,进而提升渲染性能。当两个已经存在于DOM 中的组件交换位置肘, React 能够匹配对应的键并进行相应的移动,且不需要完全重新渲染DOM 。
6、注释
在 JSX 中,注释需要写在花括号中,实例如下:
var arr = [{'name':'sean'}, {'name':'Lilei'}, {'name':'Tom'}];
ReactDOM.render(
<div>
{/*对数组进行遍历*/}
{
arr.map(function (elem, index) {
return <h3 key={index}>Hello, {elem.name}</h3>;
})
}
</div>,
document.getElementById('example')
);
7、条件判断
在 react 中,要想在组件中添加条件判断似乎是件很困难的事情,因为if/else 逻辑很难用HTML 标签来表达。直接往JSX 中加入if 语句会渲染出无效的JavaScript,解决的方法主要有以下四种(当一个加载完成时,给组件添加相应的样式):
- 使用三目运算符
render: function () {
return <div className={
this.state.isComplete ? 'is-complete' : ''
}>...</div>;
}
- 设置一个变量并在属性中引用它
getIsComplete: function () {
return this.state.isComplete ? 'is-complete' : '';
},
render: function () {
var isComplete = this.getIsComplete();
return <div className={isComplete}>...</div>;
}
- 将逻辑转化到函数中
getIsComplete: function () {
return this.state.isComplete ? 'is-complete' : '' ;
},
render: function () {
return <div className={this.getIsComplete()}> . ..</div>;
}
- 使用 && 算符
由于对于null 或false 值React 不会输出任何内容, 因此你可以使用一个后面跟随了期望字符串的布尔值来实现条件判断。如果这个布尔值为true , 那么后续的字符串就会被使用。
render: function () {
return <div className={this.state.isComplete && 'is-complete'}>
...
</div>;
}