JSX深入详解

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的语法格式,而不是说JSXhtml的补充或拓展。

接下来说说注释,在以往的项目里中,没有提到注释,但在代码编写中,注释是很重要的组成部分。JSX中的注释跟普通的javascript注释稍微有些不同,如果我们的注释夹杂在标签之间,那么我们需要使用大括号把注释的内容包起来,例如: 

ReactDOM.render(
	<div className="main">
		<p class="content">Hello</p> 
		{/* this is a comment*/} 
		<Label/>
	</div>, 
	document.querySelector("container") 
}

"this is comment" 就是注释内容,但由于它夹杂在标签pLabel之间,所以它需要使用一个大括号包围起来。如果注释是落在标签里面的话,大括号就可以省掉了,例 : 

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是不可能做到的。 







發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章