简介JSX

1,189 阅读5分钟

JSX是什么

接触过react或者vue的同学可能知道或者了解jsx,我也接触react两年了,但是昨天我问了自己一下‘jsx是什么’,我却不能流利回答处理,只是一直使用,却不知道jsx的来源,于是我就去react官网查看《草案:jsx规范》给大家分享一下

1、jsx是什么?

在ECMAScript 第六版的草案中是这样定义的:“jsx是类似xml的语法扩展,没有任何定义的语义,不是由浏览器和引擎实现的,它旨在被各种预处理器处理后变成标准ECMAScript” 如果不怎么了解ECMAScript可以查看《js的组成部分》

2、该语法扩展的规范是什么?

用于定义带有属性树结构的简明且熟悉的语法,能够定义良好的语法并使用独立的解析器和语法高亮显示的社区能够符合单个规范

3、创建的目的是什么?

在保持独立语法简洁且熟悉的情况下创建最小的语法空间。

4、jsx选择类型引用

在起初现在类型引用的时候,曾尝试够一下几种

  • 1 ECMAScript第六版版本的模板文字`string ${ varate

    看下代码,模板文字用在这是不合适,语法的噪声太大,可读性差。

// Template Literals
var box = jsx`
  <${Box}>
    ${
      shouldShowAnswer(user) ?
      jsx`<${Answer} value=${false}>no</${Answer}>` :
      jsx`
        <${Box.Comment}>
         Text Content
        </${Box.Comment}>
      `
    }
  </${Box}>
`;
  • 2 ECMAScript第五版版本的JSON{"key":"value"}

另一种选择是使用对象初始化器(类似于JXON)。不幸的是,平衡的大括号没有给出元素在大树中开始和结束的地方的语法提示。平衡的命名标记是XML样式表示法的关键语法特征。

const element = "<div>{"key":"value"}</div>"
  • 3 PrimaryExpression

因此,最好将JSX作为一种全新的PrimaryExpression类型引入:

// JSX
var box =
  <Box>
    {
      shouldShowAnswer(user) ?
      <Answer value={false}>no</Answer> :
      <Box.Comment>
         Text Content
      </Box.Comment>
    }
  </Box>;

5 jsx语法扩展使用

咱们在上面已经了解了jsx是什么,为什么定义jsx,他的规范是什么,jsx选择的引用类型是什么,那么咱们就看看常见jsx

//1 jsx是严格闭合的

     const Element = <h1>// error
     
     const Element = <h1/>// right
     const Element = <h1></h1>// right
 
 //2 jsx 可以作为变量的值
     
      const Element = <h1>string</h1>
      
 //3 jsx 嵌套规则 只能有一个父级节点
  
      //error
      const Element = <div>string</div> <div>string2</div>
      
      //rigth
        const Element = <div>
                            <div>string1</div> 
                            <div>string2</div> 
                        </div> 
//4 jsx自定的组件必须大写

    // error 在第三方使用的jsx的时候某些转换器转换的时候 会直接当中element标签解析
    const element = <div>
                        <div>string1</div> 
                        <div>string2</div> 
                    </div> 

    // right
    const Element = <div>
                        <div>string1</div> 
                        <div>string2</div> 
                    </div> 

6 在js中使用

//在react中使用
    //1 使用变量
    
        const  TEXT = 'this is variate'
        const Element = <div> { TEXT } </div>
        ReactDom.render(<Element/>, document.getElementById('root'))
    
     //2 使用Array 
         const arr = [
          'this is variate',
          'this is variate'
         ]
        
        const Element = <div>{
                         arr.map(( item, index )=>(<div id={index} >{item} </div>))
                        }</div>
        ReactDom.render(<Element/>,document.getElementById('root'))
    
    //3 使用条件判断
    
        //error 在jsx中一般转换器不支持直接使用if
        const  TEXT = 'this is variate'
        const Element = <div>{if(1==2){TEXT}}</div>
        ReactDom.render(<Element/>,document.getElementById('root'))

        //right 但是使用三目运算费和逻辑|| 或者 && 一般转换器是可以的
        
        // 三目运算
        const  TEXT = 'this is variate'
        const Element = <div>{1==2?TEXT:''}</div>
        ReactDom.render(<Element/>,document.getElementById('root'))
        // || 
        const  TEXT = 'this is variate'
        const Element = <div>{false||true?TEXT:''}</div>
        ReactDom.render(<Element/>,document.getElementById('root'))
        // &&
        const  TEXT = 'this is variate'
        const Element = <div>{false&&true?TEXT:''}</div>
        ReactDom.render(<Element/>,document.getElementById('root'))
    
    //4 使用ECMAScript 第六版的结构赋值 ‘...’
      const  TEXT = 'this is variate'
      const props = { onClick:()=>{}, data:'this is data' }
        const Element = <div> {false && true? TEXT : '' } </div>
        ReactDom.render(<Element {...props}/>,document.getElementById('root'))
        
    // 5 jsx的注释
        // 5.1 外部注释
            //error 注释时必须把一个整的标签都注释掉
            <div>
            //    <div>string1</div> 
            //    <div>string2</div> 
           // </div> 
        
            // right
            //<div>
            //    <div>string1</div> 
            //    <div>string2</div> 
           // </div> 
          
        // 5.2 内部注释
            //error 注释时必须把一个整的标签都注释掉
            <div>
               {
                   /*
                   variate
                   */
               }
            </div>
        

7 JSX和HTML、XML的区别

JSX规范不会尝试遵守任何XML或HTML规范。JSX被设计为ECMAScript功能,与XML的相似之处仅在于熟悉。

7.1 在jsx在js中使用时,可以看到jsx可以直接使用变量、数组、三目运算、方法等,但是html是不可以直接使用的

7.2 HTML中使用的class作为css的名字在jsx中是不可以使用,因为在jsx中认为class为关键字。就像js使用className

    const variate='this is a variate'
    const Element = <div className = 'test'>{variate}</div>

7.3 HTML中使用的style作为css的行内样式,而在jsx就像js使用style一样

    const variate='this is a variate'
    const Element = <div style = {{height:'89px',overFlow:'auto'}}>{variate}</div>

7.4 jsx 中的事件名称都以小驼峰命名

    const variate='this is a variate'
    const Element = <div onClick={()=>{}} onChage={()=>{}}>{variate}</div>

7.5 一些属性只有在jsx中存在

  • 1 key
  • 2 ref
  • 3 dangerouslySetInnerHTML

7.6 jsx防止注入攻击

const title = response.potentiallyMaliciousInput;
// This is safe:
const element = <h1>{title}</h1>;

默认情况下,一些语言渲染之前转义 JSX中嵌入的任何值。因此,它确保您永远不会注入未在应用程序中明确写入的任何内容。在渲染之前,所有东西都被转换为字符串。这有助于防止XSS(跨站点脚本)攻击。

8 为什么react要选择jsx

react不需要使用jsx,但是大多人发现在JavaScript代码中使用UI时,jsx作为视觉辅助工具很有用。jsx允许react显示更多有用的错误警告。

结合上面中jsx在js中使用的快捷高效何乐而不为。

在react中jsx,会被babel编译成 React.createElement()调用

const element = (
  <h1 className="greeting">
    Hello, world!
  </h1>
);
const element = React.createElement(
  'h1',//type
  {className: 'greeting'},//props
  'Hello, world!'//text
);
//React.createElement()