React学习笔记-2-什么是jsx?如何使用jsx?
- 什么是jsx?
JSX是JavaScript XML 这两个单词的缩写,xml和html非常类似,简单来说可以把它理解成使用各种各样的标签,大家可以自行 百度。所以jsx就是在javascript中来编写长得很像xml的语言,这里只是像,在本质上是不一样的。
jsx是一种基于Ecmascript的一种新特性,
是一种定义带属性树结构的语法,树结构就是我们的dom结构,属性就是dom节点中的属性,比如所class,id等
jsx不是xml或者Html,
不是一种限制。在react中,我们可以使用jsx来编写代码,也可以使用纯javascript来编写代码,所以说即使你不学jsx也可以正常使用react,但是Facebook官方腿甲使用jsx来编写。 - 为什么我们要使用jsx呢?
因为jsx有五个特点
第一个:类xml语法容易接受,在实际的工程中,还有别的人员接触前端代码,比如设计师,测试等等,他们很多人可能不熟悉javascript,但是很多人熟悉xml
第二个:增强js的语义,js主要体现在界面的逻辑方面,但是对于界面元素的表现,js是比较弱的,在不使用jsx之前,大部分时候我们使用的是模板,模板其实就是一段字 符串,你在模板里面写东西是可以的,模板的问题在于他页面的内容本身是分离的,并且模板本身是字符串,我们很难对其进行扩展,但是jsx是直接在js的基础上去编写
html,他的本质并不是字符串,就是js语言本身,所以说他可以在语义层面上增强js
第三个:结构清晰,使用jsx来编写代码,我们通过代码就可以知道生成的结果是什么,就像看html代码一样。
第四个:抽象程度高,带来的第一个好处就是,react屏蔽掉了所有的手动dom操作,之所以能够屏蔽dom操作,就是因为他像上提供了一个新的抽象层,作为开发者我们
只需要关注这一个抽象层,而不必关心抽象层下面到底是如何去实现的,从而屏蔽掉了手动的dom操作,抽象带来的第二个好处就是跨平台,从而诞生了react native。 为什么可以跨平台呢?你使用jsx去编写的时候,其实是独立于平台的语法,你设计是平台本身,react完全可以在不同的平台上提供解释器,从而可以让你的代码执行在不 同的平台上,所以我们说抽象是jsx的核心。
第五个:代码模块化,在传统的MVC开发中,MVC其实是分离的,无论是在概念上,还是在实际的代码上,他们三者往往都不会放在一起,但是在react中,我们发现,编 写一个组件的时候,他的相关代码全部都放在了一起,jsx中,既可以js的逻辑,有可以写页面的结构,乍一看,好像是不太合适,我们学到的经验是吧不同的经验区分出 来,有助于开发的进行。那react将他们都混在了一起,这样是一个好的选择吗?其实react所做的部分是一个横向的划分,MVC所做的事情是纵向的划分,也就是手MVC 把整个项目从上到下切了两刀,把它切成了三个部分,但是react所做的事情是把一个项目从左到右,切成了很多部分,或者说他既结合了从上到下,又结合了从左到右, 把一个大的项目打散成为了许多小的项目,从而实现代码的模块化,在代码的力度变得非常小的时候,我们就可以专注于一个非常具体的功能,在这种情况下,把他们的代 码都放在一起,更有助于理解,并且有助于代码本身的组织是,是想一下,如果你把你一个项目拆成了几十上百个晓得模块,你还要在每一个模块上运用MVC的方法,分 成三个甚至是更多个文件,那么这个项目本身就要维护成百上千个文件了,这是一件非常可怕的事情,所以说在我们讨论代码划分的合理性时,一定要研究清楚前提条件, 也就是代码的规模的大小. - jsx的语法
<script type="text/jsx"> var HelloMessage=React.createClass({ render:function(){ return <div className="test">Hello{this.props.name}</div>; } }); React.render(<HelloMessage name="李明"></HelloMessage>>,mountNode); </script>
看这个例子,很简单,只是实现了render函数,从上面的代码中,我们可以看出,jsx其实本质上就是js,他和js的区别就是可以直接在里面编写html标签,这在普通的js中是无法实现的,要想实现只能采用字符串的形式来拼接标签,但是在jsx中,可以原生的支持html标签。
第二个知识点:就是子节点 this.props.name,标签和标签之间可以有嵌套关系,就像我们在html中编写的一样,每个标签都可以嵌套在别的标签中,他也可以拥有很多的标签作为他的子节点,在jsx中,jsx和html嵌套不同的一点就是可以在子节点中使用求值表达式,我们可以看到图中的子节点本质上是一个文本节点,只是这个文本节点有两部分组成,第一个部分是Hello字符串,后面跟一个空格,第二部分是由大括号括起来的一个表达式,这个表达式所做的事情就是取出这个组件属性中的,name属性的值,并把它放在这个节点里,和hello+空格拼成一个完整的文本节点,至于什么是属性,我们后面说。这里只要知道每个组件都有属性,也就是props,属性内部会存很多属性和属性名。
第一个知识点:HelloMessage,元素名,我们编写的每一个组件其实也就是一个元素名,这里我们声明了一个HelloMessage标签,在最后一行中,我们将它渲染到了mountNode中,我们可以看到,渲染的时候使用的语法就是标准的html语法,直接在标签中填写标签名,只是这个标签名是我们自定义出来的。
第三个知识点就是节点属性,<HelloMessage name="李明"></HelloMessage>,这里的name就是,我们使用this.props.name来获取他的值,这个值从哪来呢,就是在使用标签的时候,我们给定的。 - 补充几个react语法的关键内容。
第一:首字母大小写。react对于首字母的大小写是敏感的,如果一个组件的首字母是大写,那么react就知道他是一个自定义的组件,如果是小写,react就会把它当做自带dom的自带元素名,比如说我们上面代码中的HelloMessage首字母就是大写,是自定义的组件,后面的div首字母是小写,因为他是dom中的组件,如果你的自定义组件首字母是小写,那么字啊render渲染的时候会出错,因为react会去dom中寻找,但是显然你自定义的组件是不会存在于dom标准组件中,所以就会出错。
第二:嵌套。组件和组件之间,就像dom和dom之间,可以进行嵌套,上面代码中我们只进行了一层嵌套,就是在div中嵌套了一个文本节点,其实可以在里面嵌套各种各样的无数节点
第三:求值表达式。求值表达式其实和jsx本身是没有什么关系的,他是作为js本身的一个特性,js中有几种语法元素,比如关键字,语句,表达式等等,那么求值表达式是什么意思?就是他本身是一个表达式,他会返回一个值,这里我们需要强调的是求值表达式和语句本质上是不一样的,也就是说,我们在编写jsx的时候,大括号里面,不可以使用语句,比如if语句,for语句,switch语句等,都是不可以的,但是求值表达式可以的,那我们应该如何去区分求值表达式和和语句呢?多个表达式可以联合使用,但是语句是不可以的,比如图中的this.props.name是一个字符串形式的表达式,他会返回一个字符串,我们可以对他进行一些运算,比如说给他加个abc,做字符串的加法,把他们连到一起,这是可以的,但是如果是是个if语句,你是不能在if语句进行运算的,语句是不能进行运算的,但是表达式可以,所以区分表达式和语句的方法就是看他能不能进行运算。虽然我们不能直接使用if等语句,但是我们可以把它包裹在函数求值表达式中,从而在函数求值表达式内部来使用这个语句,但是这个函数本身是一个表达式,所以我们可以把它用在jsx的大括号中,这样我们就实现了可以在大括号中运行各种语句,但是在实际使用中,这并不是一个很好的情况,如果有这样的情况,建议把它独立出来,然后在大括号中来调用这个函数。
第四:驼峰命名。jsx标签使用的是驼峰命名,函数名也是。
第五:两个特殊的属性。html的标签中可以使用html属性和class属性,但是我们现在是在js的上下文中区编写html文件,html和class是js得保留字和关键字,所以我们不能直接把他写在js中,jsx解决这个问题的办法就是使用两个别名来代替他们,也就是htmlFor和className,如果我们要使用html和class属性,我们实际要写的是htmlFor和className,在解释器解释的时候,会自动把他们一一对应过去,可以看到我们上面的代码中,div的class就是写的className。直接使用会报错。 - jsx语法实例---注释
添加注释有两种方法,第一种是多行注释,使用/**/,第二种是单行注释,使用//,
注释可以放在两个部分。
第一个部分:子节点中,也就是标签包裹的这一部分,这里需要使用大括号来包裹注释。下面的代码中,HelloWorld后面。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>hello world</title> </head> <body> <script type="text/javascript" src="http://cdn.bootcss.com/react/0.13.2/react.js"></script> <script type="text/javascript" src="http://cdn.bootcss.com/react/0.13.2/JSXTransformer.js"></script> <script type="text/jsx"> var HelloWorld=React.createClass({ render: function(){ return <p>Hello,world{ /* 这是一个多行注释 */ //这是一个单行注释 }</p> } }); React.render(<HelloWorld></HelloWorld>,document.body); </script> </body> </html>
第二个部分:属性中,也就是标签本身这里
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>hello world</title> </head> <body> <script type="text/javascript" src="http://cdn.bootcss.com/react/0.13.2/react.js"></script> <script type="text/javascript" src="http://cdn.bootcss.com/react/0.13.2/JSXTransformer.js"></script> <script type="text/jsx"> var HelloWorld=React.createClass({ render: function(){ return <p /* 这是一个注释 */ name="李明"//这里是一个属性,单行注释也可以和属性放在同一行 //这是一个单行注释 >Hello,world { /* 这是一个多行注释,放在了子节点中 */ "Jerry"//他是字符串,由于被包裹在大括号中,本身应该是js,所以应该用双引号包裹 //我是单行注释 } </p> } }); React.render(<HelloWorld></HelloWorld>,document.body); </script> </body> </html>
- jsx语法实例--如何在jsx里面书写css样式。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>hello world</title> </head> <body> <script type="text/javascript" src="http://cdn.bootcss.com/react/0.13.2/react.js"></script> <script type="text/javascript" src="http://cdn.bootcss.com/react/0.13.2/JSXTransformer.js"></script> <script type="text/jsx"> var style={ color:"red", border:"1px solid #f09", }; var HelloWorld=React.createClass({ render: function(){ return <p>Hello,world</p> } }); React.render(<div style={style}><HelloWorld></HelloWorld></div>,document.body); </script> </body> </html>
需要注意的是其他属性的赋值一般是字符串,但是style 属性的赋值一般是一个对象,这是因为style属性比较特殊,react会把style里面自定义的属性,正确的应用到style上面,
React.render(<div style={style}><HelloWorld></HelloWorld></div>,document.body);
- jsx语法实例:嵌套
6中的实例就有演示,如下代码
React.render(<div style={style}><HelloWorld></HelloWorld></div>,document.body);
我们将我们的自定义组件HelloWorld放到了div中,实际开发中,我们可以嵌套无数个。
- 条件判读的四种写法
if语句不是一个表达式,他是一个语句,所以说在编写jsx代码的时候,我们不能直接使用if语句,但是我们可以使用四种表达式来实现相同的效果
我们实现这个功能,如果传入属性name的值,我们就输出name的值,如果没有,我们就输出world
8.1使用三元表达式
如果我们直接使用 if....else语句会直接报错,代码如下。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>hello world</title> </head> <body> <script type="text/javascript" src="http://cdn.bootcss.com/react/0.13.2/react.js"></script> <script type="text/javascript" src="http://cdn.bootcss.com/react/0.13.2/JSXTransformer.js"></script> <script type="text/jsx"> var style={ color:"red", border:"1px solid #f09", }; var HelloWorld=React.createClass({ render: function(){ return <p>Hello,{ if(this.props.name) this.props.name esle "world" }</p> } }); React.render(<div style={style}><HelloWorld></HelloWorld></div>,document.body); </script> </body> </html>
所以这里我们使用三元表达式,如下代码,可以吧HelloWorld里,name的属性去掉以后,在看看效果
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>hello world</title> </head> <body> <script type="text/javascript" src="http://cdn.bootcss.com/react/0.13.2/react.js"></script> <script type="text/javascript" src="http://cdn.bootcss.com/react/0.13.2/JSXTransformer.js"></script> <script type="text/jsx"> var style={ color:"red", border:"1px solid #f09", }; var HelloWorld=React.createClass({ render: function(){ return <p>Hello,{this.props.name ? this.props.name : "world"}</p> } }); React.render(<div style={style}><HelloWorld name="李明"></HelloWorld></div>,document.body); </script> </body> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>hello world</title> </head> <body> <script type="text/javascript" src="http://cdn.bootcss.com/react/0.13.2/react.js"></script> <script type="text/javascript" src="http://cdn.bootcss.com/react/0.13.2/JSXTransformer.js"></script> <script type="text/jsx"> var style={ color:"red", border:"1px solid #f09", }; var HelloWorld=React.createClass({ getName:function(){ if(this.props.name) return this.props.name else return "world" },//这里有逗号,切记 render: function(){ var name=this.getName(); return <p>Hello,{name}</p> } }); React.render(<div style={style}><HelloWorld name="李明"></HelloWorld></div>,document.body); </script> </body> </html>
8.3改8.2中的例子,直接把大括号去掉,直接调用<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>hello world</title> </head> <body> <script type="text/javascript" src="http://cdn.bootcss.com/react/0.13.2/react.js"></script> <script type="text/javascript" src="http://cdn.bootcss.com/react/0.13.2/JSXTransformer.js"></script> <script type="text/jsx"> var style={ color:"red", border:"1px solid #f09", }; var HelloWorld=React.createClass({ getName:function(){ if(this.props.name) return this.props.name else return "world" },//这里的逗号 render: function(){ return <p>Hello,{this.getName()}</p> } }); React.render(<div style={style}><HelloWorld name="李明"></HelloWorld></div>,document.body); </script> </body> </html>
8.4使用比较计算符
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>hello world</title> </head> <body> <script type="text/javascript" src="http://cdn.bootcss.com/react/0.13.2/react.js"></script> <script type="text/javascript" src="http://cdn.bootcss.com/react/0.13.2/JSXTransformer.js"></script> <script type="text/jsx"> var style={ color:"red", border:"1px solid #f09", }; var HelloWorld=React.createClass({ render: function(){ return <p>Hello,{this.props.name || "world"}</p> } }); React.render(<div style={style}><HelloWorld name="李明"></HelloWorld></div>,document.body); </script> </body> </html>
- 万能的函数表达式
通常情况下,函数声明并不是一个表达式,而是一个语句,但是我们可以通过特殊的方式,将它改成表达式,从而可以直接调用函数获取返回值,由于他是一个表达式,我们可以把它用在大括号中,我们看下面的例子。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>hello world</title> </head> <body> <script type="text/javascript" src="http://cdn.bootcss.com/react/0.13.2/react.js"></script> <script type="text/javascript" src="http://cdn.bootcss.com/react/0.13.2/JSXTransformer.js"></script> <script type="text/jsx"> var style={ color:"red", border:"1px solid #f09", }; var HelloWorld=React.createClass({ render: function(){ return <p>Hello,{ (function(obj){ if(obj.props.name) return obj.props.name else return "world" })(this) }</p> } }); React.render(<div style={style}><HelloWorld name="李明"></HelloWorld></div>,document.body); </script> </body> </html>
这个例子要注意理解强制求值运算,也就是把function包裹起来的那个括号,在这个括号里面的function会被强制求值运算,他会返回一个函数的引用,然后我们又在后面加了一个(this),用()来调用他, 并传入一个this,就可以实现我们想要的效果
(function(obj){ })(this)
这个括号还有一种写法,就是把(this)前面的括号放到后面,具体看代码,也是可以的。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>hello world</title> </head> <body> <script type="text/javascript" src="http://cdn.bootcss.com/react/0.13.2/react.js"></script> <script type="text/javascript" src="http://cdn.bootcss.com/react/0.13.2/JSXTransformer.js"></script> <script type="text/jsx"> var style={ color:"red", border:"1px solid #f09", }; var HelloWorld=React.createClass({ render: function(){ return <p>Hello,{ (function(obj){ if(obj.props.name) return obj.props.name else return "world" }(this)) }</p> } }); React.render(<div style={style}><HelloWorld name="李明"></HelloWorld></div>,document.body); </script> </body> </html>
括号放在外面和里面的区别,放在里面的时候,括号执行完毕拿到的是函数的引用,然后在调用他,但是括号放在外面的时候,弄到的直接就是返回值,而不是函数引用本身。建议大家看看this的用法。
这是我自己学习,工作做的笔记和总结,只是做个记录,没事的时候翻翻!有问题大家可以提出来,一起探讨,共同进步。如有转载,请注明出处。