首页 > 代码库 > React学习笔记-2-什么是jsx?如何使用jsx?

React学习笔记-2-什么是jsx?如何使用jsx?

  1. 什么是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来编写。


  2. 为什么我们要使用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的方法,分     成三个甚至是更多个文件,那么这个项目本身就要维护成百上千个文件了,这是一件非常可怕的事情,所以说在我们讨论代码划分的合理性时,一定要研究清楚前提条件,   也就是代码的规模的大小.


  3. 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标签。

    第一个知识点:HelloMessage,元素名,我们编写的每一个组件其实也就是一个元素名,这里我们声明了一个HelloMessage标签,在最后一行中,我们将它渲染到了mountNode中,我们可以看到,渲染的时候使用的语法就是标准的html语法,直接在标签中填写标签名,只是这个标签名是我们自定义出来的。

    第二个知识点:就是子节点 this.props.name,标签和标签之间可以有嵌套关系,就像我们在html中编写的一样,每个标签都可以嵌套在别的标签中,他也可以拥有很多的标签作为他的子节点,在jsx中,jsx和html嵌套不同的一点就是可以在子节点中使用求值表达式,我们可以看到图中的子节点本质上是一个文本节点,只是这个文本节点有两部分组成,第一个部分是Hello字符串,后面跟一个空格,第二部分是由大括号括起来的一个表达式,这个表达式所做的事情就是取出这个组件属性中的,name属性的值,并把它放在这个节点里,和hello+空格拼成一个完整的文本节点,至于什么是属性,我们后面说。这里只要知道每个组件都有属性,也就是props,属性内部会存很多属性和属性名。

    第三个知识点就是节点属性,<HelloMessage name="李明"></HelloMessage>,这里的name就是,我们使用this.props.name来获取他的值,这个值从哪来呢,就是在使用标签的时候,我们给定的。


  4. 补充几个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。直接使用会报错。


  5. 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>



  6. 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);

     



  7. jsx语法实例:嵌套
    6中的实例就有演示,如下代码
            React.render(<div style={style}><HelloWorld></HelloWorld></div>,document.body);

    我们将我们的自定义组件HelloWorld放到了div中,实际开发中,我们可以嵌套无数个。

  8. 条件判读的四种写法
    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>

     

    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(){
               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>

     

  9. 万能的函数表达式
    通常情况下,函数声明并不是一个表达式,而是一个语句,但是我们可以通过特殊的方式,将它改成表达式,从而可以直接调用函数获取返回值,由于他是一个表达式,我们可以把它用在大括号中,我们看下面的例子。
    <!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的用法。

React学习笔记-2-什么是jsx?如何使用jsx?