亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

理解JSX

W4n9Hu1 / 2870人閱讀

摘要:原本是有自己的來負(fù)責(zé)的解析,不過現(xiàn)在已經(jīng)停止更新,語(yǔ)法完全依賴進(jìn)行解析。關(guān)于上面的幾個(gè)轉(zhuǎn)碼的結(jié)果的解釋都在下面的源碼中這里可以發(fā)現(xiàn),支持,但是比如就一定會(huì)報(bào)錯(cuò)了,雖然看起來與一樣

首先jsx絕不是一個(gè)新的語(yǔ)言,我覺得他僅僅是js的超集,或者只是一種語(yǔ)法糖。原本FB是有自己的jsx-transform來負(fù)責(zé)jsx的解析,不過現(xiàn)在已經(jīng)停止更新,jsx語(yǔ)法完全依賴babel進(jìn)行解析。

babel

babel在識(shí)別jsx的時(shí)候,會(huì)將標(biāo)簽直接作為AST的node,然后轉(zhuǎn)化

class Square extends React.Component {
  render() {
    return (
      
    );
  }
}

將被babel轉(zhuǎn)化為

class Square extends React.Component {
  render() {
    return React.createElement(
      "button",
      { className: "square" },
      this.props.value
    );
  }
}

這里為了方便和閱讀對(duì)es6的轉(zhuǎn)化,暫時(shí)忽略。

AST

還是針對(duì)上面的代碼,來看一下babylon AST的解析結(jié)果,只包含return部分
整個(gè)標(biāo)簽部分是JSXElement
其中會(huì)有三個(gè)部分openingElement,closingElement和children,屬性則會(huì)成為openingElement的JSXAttribute

jsx在babel的定義

defineType("JSXElement", {
  builder: ["openingElement", "closingElement", "children", "selfClosing"],
  visitor: ["openingElement", "children", "closingElement"],
  aliases: ["JSX", "Immutable", "Expression"],
  fields: {
    openingElement: {
      validate: assertNodeType("JSXOpeningElement"),
    },
    closingElement: {
      optional: true,
      validate: assertNodeType("JSXClosingElement"),
    },
    children: {
      validate: chain(
        assertValueType("array"),
        assertEach(
          assertNodeType(
            "JSXText",
            "JSXExpressionContainer",
            "JSXSpreadChild",
            "JSXElement",
            "JSXFragment",
          ),
        ),
      ),
    },
  },
});

AST的jsx節(jié)點(diǎn)最后會(huì)被替換為createElement的形式,也就是說不管怎么用jsx,其實(shí)也就只是一種語(yǔ)法糖,與createElement的寫法無異

e.g

為了更好的理解jsx,那我解釋一段最近看到的代碼

methodsParamsList.map((ListSourceComponent, index) => {
       return 
})

核心也就是openingElement

在babel的眼里他做為Element有兩個(gè)部分,名字和屬性,屬性不多說了。
ListSourceComponent.component會(huì)被認(rèn)為是JSXMemberExpression,ListSourceComponent是JSXIdentifier的對(duì)象component則是屬性
如果是

那么ListSourceComponent是JSXIdentifier的name

整個(gè)代碼的結(jié)果也就是

 methodsParamsList.map((ListSourceComponent, index) => {
      return React.createElement(ListSourceComponent.component, { index: index + 1 });
    });

其實(shí)在轉(zhuǎn)碼的階段是否將JSXMemberExpression的name或者對(duì)象的首字母大寫是不重要的,真的導(dǎo)致報(bào)錯(cuò)的也不過是在createElement中

createElement
createElement()

React.createElement(type, [props],[...children])

Create and return a new React element of the given type. The type argument can be either a tag name string (such as "div" or "span"), or a React component type (a class or a function).
Code written with JSX will be converted to use React.createElement(). You will not typically invoke React.createElement() directly if you are using JSX. See React Without JSX to learn more.

reactComponent大寫的原因

在剛學(xué)react的時(shí)候,老師就說過react component需要大寫,react會(huì)把大寫開口的作為react的組件,不然則會(huì)使普通的html dom,比如div,span
首先是不是在解析ast的時(shí)候就把大小寫分開處理了,答案是否定的,在定義openingElement的type的時(shí)候完全沒有對(duì)這個(gè)進(jìn)行判斷,不管是大寫,小寫均作為string,是element的type
但是在babel的結(jié)果里可以看到
React.createElement("div", ...)
React.createElement( Div, ...)
這兩種結(jié)果帶來的就是Div這個(gè)是一個(gè)字符串還是變量名,如果自己不慎寫了個(gè)小寫的component名,那么一個(gè)并不是html標(biāo)簽的字符串必然會(huì)造成錯(cuò)誤
這里必須穿插一個(gè)JSX dot notation

JSX dot notation

這個(gè)和上面的例子相關(guān)就是dot notation在jsx中的解析

methodsParamsList.map((ListSourceComponent, index) => {
       return 
    })
methodsParamsList.map((listSourceComponent, index) => {
       return 
    })

上面兩段代碼都不會(huì)導(dǎo)致錯(cuò)誤,原因就是在解析JSXIdentifier的結(jié)果會(huì)是一組對(duì)象和屬性,所以轉(zhuǎn)碼結(jié)果一定不是字符串而是obj.pro

jsx的變形

上面說到了在構(gòu)建ast的過程中大小寫并不進(jìn)行區(qū)分,而是在@babel/plugin-transform-react-jsx中進(jìn)行變化。
關(guān)于上面的幾個(gè)轉(zhuǎn)碼的結(jié)果的解釋都在下面的源碼中

  const createIdentifierParser = (id: string) => () => {
    return id
      .split(".")
      .map(name => t.identifier(name))
      .reduce((object, property) => t.memberExpression(object, property));
  };

這里可以發(fā)現(xiàn),react支持dot notation,但是比如

就一定會(huì)報(bào)錯(cuò)了,雖然看起來與

一樣

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/93556.html

相關(guān)文章

  • 精益 React 學(xué)習(xí)指南 (Lean React)- 1.2 JSX 語(yǔ)法

    摘要:需要提醒讀者的是,的很多例子都是通過來寫的,但這并不是語(yǔ)法,后面我們會(huì)有單獨(dú)的一小節(jié)講解的基本語(yǔ)法,不過目前為止我們先將跟多精力放在上。 書籍完整目錄 1.2 JSX 語(yǔ)法 showImg(https://segmentfault.com/img/bVvKLR); 官方文檔 https://facebook.github.io/react/docs/jsx-in-depth.html ...

    moven_j 評(píng)論0 收藏0
  • 虛擬DOM內(nèi)部是如何工作的

    摘要:但是它與里大部分的概率是保持一致的。但是如何將轉(zhuǎn)換成函數(shù)的調(diào)用呢就是干這件事情的。好了,讓我們看看是如何工作的。下面的圖片在流程圖中高亮了一個(gè)組件是如何工作的最后希望這篇文章能幫助你理解是如何工作的至少在中 英文原文鏈接 Virtual DOM很神奇,同時(shí)也比較復(fù)雜,難以理解。react,preact和相似的js庫(kù)都使用了virtual dom。然而,我找不到任何好的文章或者文檔,可以...

    hiYoHoo 評(píng)論0 收藏0
  • React.js學(xué)習(xí)筆記之JSX解讀

    摘要:學(xué)習(xí)筆記之解讀前端技術(shù)不多說,大腿很粗什么是是的核心組成部分,它使用標(biāo)記的方式去直接聲明界面,界面組件之間可以互相嵌套。它的目的是通過各種編譯器將這些標(biāo)記編譯成標(biāo)準(zhǔn)的語(yǔ)言。的標(biāo)簽與函數(shù)名都是使用的駝峰命名。目前,一個(gè)的,只能返回一個(gè)節(jié)點(diǎn)。 React.js學(xué)習(xí)筆記之JSX解讀 @(前端技術(shù)) Why React? 不多說,F(xiàn)acebook大腿很粗 什么是JSX JSX是React的核心...

    tianlai 評(píng)論0 收藏0
  • React.js 小書 Lesson7 - 組件的 render 方法

    摘要:一個(gè)組件類必須要實(shí)現(xiàn)一個(gè)方法,這個(gè)方法必須要返回一個(gè)元素。你也可以把它改成,它就會(huì)顯示小書。注意,直接使用在的元素上添加類名如這種方式是不合法的?,F(xiàn)在頁(yè)面上是顯示小書。下一節(jié)中我們將介紹小書組件的組合嵌套和組件樹。 React.js 小書 Lesson7 - 組件的 render 方法 本文作者:胡子大哈本文原文:http://huziketang.com/books/react/l...

    Near_Li 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<