JSX是一种类似于html标签组合的语法对象,JSX实例如下:
var Card = React.createClass({
render: function() {
return (
<div>
<Square color={this.props.color}/>
<Label color={this.props.color}/>
</div>
)
}
})
return 返回的那一段标签代码,我们就称之为JSX. 它跟html很像,但又不是html, 因为标准html中根本不存在Square, Label 这种标签。因此,如果我们直接把这段标签代码提交给浏览器,浏览器是识别不了的。但为何最终这段代码被浏览器加载后能够正确的发挥作用呢?这就要依赖于React 提供的Babel组件了,你可以认为,Babel 是一个编译器,他把浏览器识别不了的JSX标签代码,编译成浏览器能识别的javascript代码。
那么这段JSX代码被Babel翻译后会变成什么样子呢,它们经过转换后会变成如下形式:
return React.createElement("div",
React.createElement(Square,{color:this.props.color}),
React.createElement(Label,{color:this.props.color})
)
React 本身是 个js 对象,通过createElement返回的也是 个js 对象。也就是说,尽管我们写代码时,需要依赖于 个JSX的概念,但当浏览 加载代码前,Babel这个编译 先把代码进 次转换,然后再把转换后的代码提交给浏览 执行,因此浏览 运 的代码是 存在JSX这种形式的。
由于存在这种隐形的转换过程,因此在使 JSX的时候,有不少我们需要注意的地方。 先需要注意的是JSX对象必须要有一个根节点, 如以下代码是错误的:
ReactDOM. render(
<Letter>A</Letter>
<Letter>E</Letter>
<Letter>I</Letter>
<Letter>O</Letter>
,
document.querySelector("container")
);
Letter是一个React组件,上面的代码把一个React组件并排放在一起,上面的代码如果经过Babel编译转换的话,会变成以下形式:
ReactDOM.render( React.createElement(Letter, null, "A"),
React.createElement(Letter, null, "E"),
React.createElement(Letter, null, "I"),
React.createElement(Letter, null, "O"),
docuyment.querySelector("container"))
render 函数只接受两个参数,但是上面代码转义后,render被传入多个参数,因此就要导致错误,所以正确的做法是,要在多个并列的React组件之上加上一个根元素。
ReactDOM. render(
<div>
<Letter>A</Letter>
<Letter>E</Letter>
<Letter>I</Letter>
<Letter>O</Letter>
</div>,
document.querySelector("container")
);
上面代码被babel转义之后形式如下:
ReactDOM.render(
React.createElement(div, null,
React.createElement(Letter, null, "A"),
React.createElement(Letter, null, "E"),
React.createElement(Letter, null, "I"),
React.createElement(Letter, null, "O"),
),
docuyment.querySelector("container")
)
也就是说render函数被调用是,传给它的只有两个参数。第二点需要注意的是,不要直接在JSX中使 css代码。例如下面的代码就是错误的:
<div style="font-family: sans-serif">
<p>Hello</p>
</div>
如果想要在JSX中设置界面显示属性,必须把这些属性作为一个style对象的属性来设置,所以想要把界面显示逻辑写到React 组件时,必须先把对应的css属性转换成json对象的属性,然后通过style关键字,把这些属性设置到JSX中,这样React才能正确解读, 如如下代码:
var Letter = React.createClass({ render: function() {
var letterStyle = {
padding: 10,
margin: 10,
backgroundColor: this.props.bgcolor, display: "#333",
fontFamily: "monospace",
fontSize: "32",
textAlign = "center"
};
return (
<div style={letterStyle}>{this.props.children} </div>
) }
})
需要注意的是,style对象里面的属性跟css的属性是一一对应的,如果css的属性是 个连接词,也就是两个单词间使 "-"来链接,那么在style 对象 ,需要把它们转换成骆驼格式,此外如果在css中,属性的值对应的是字符串,那么在style对象中,需要转换成双引号包含对应的字符 。
在html的标签中,可以通过class关键字来设置该对象的类属性。但在React里,class是有特殊用途的关键字,所以在JSX中,想要给某个标签添加class属性时,必须使用关键字className, 而不能使用class.
JSX代码片段正是因为跟html有这些区别,所以我们说JSX支 持类html的语法格式,而不是说JSX是html的补充或拓展。
接下来说说注释,在以往的项目里中,没有提到注释,但在代码编写中,注释是很重要的组成部分。JSX中的注释跟普通的javascript注释稍微有些不同,如果我们的注释夹杂在标签之间,那么我们需要使用大括号把注释的内容包起来,例如:
ReactDOM.render(
<div className="main">
<p class="content">Hello</p>
{/* this is a comment*/}
<Label/>
</div>,
document.querySelector("container")
}
"this is comment" 就是注释内容,但由于它夹杂在标签p和Label之间,所以它需要使用一个大括号包围起来。如果注释是落在标签里面的话,大括号就可以省掉了,例 :
ReactDOM.render({
<div>
<Label
/* this is comment in label*/
className="label" />
</div>
});
注意大小写! 在JSX中,如果标签属于html标准控件,那么该标签的名字必须小写,如果标签属于React组件,那么组件变 名称首字母必须大写,要不然React就不会加载对应的控件。JSX只包含html标准控件,标签的名称都是小写 ,JSX中包含 React控件的话,那么控件首字符必须大写 。
组件可以作为JS变量在代码中随处引用。例
var myComponent = <MyComponent color="red"/>
ReactDOM.render(
<div>
{myComponent}
</div>,
document.querySelector("container")
)
我们在一段JSX代码中引用了一个组件,这段JSX代码可以赋值给一个变量,这个变量以后就可以使用在其他JSX代码中。
结论:
JSX不是HTML.它看起来和用起来跟html很像,但它经过React Babael组件的转义后,会变成一段js代码。也就是说JSX本身其实具备着运用业务逻辑的功能,这点html是不可能做到的。