簡介JSX

zhangfaliang發表於2019-01-17

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() 
複製程式碼