溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

react element指的是什么

發(fā)布時(shí)間:2023-01-28 09:42:00 來源:億速云 閱讀:112 作者:iii 欄目:web開發(fā)

本篇內(nèi)容介紹了“react element指的是什么”的有關(guān)知識(shí),在實(shí)際案例的操作過程中,不少人都會(huì)遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

react element是“React.createElement”函數(shù)的返回值,即ReactElement;ReactElement的結(jié)構(gòu)是“const element = {Element    $$typeof: REACT_ELEMENT_TYPE,key: key,ref: ref,props: props,_owner: owner, };”。

React源碼 | ReactElement

說到ReactElement,不得不提到的就是在React中,用來替代JavaScript(JS)的語(yǔ)言,JSX。

JSX

作為React的官方指定語(yǔ)法,JSX允許用戶在JS代碼中插入HTML代碼。但是,這種寫法瀏覽器是無法解析的。他們需要一個(gè)轉(zhuǎn)換器,Babel就充當(dāng)了這樣一個(gè)角色,他在JSX代碼編譯時(shí)候?qū)⑵滢D(zhuǎn)換成JS文件,這樣瀏覽器就能解析了。

怎么轉(zhuǎn)換呢,我們知道,JSX有JS和HTMl兩種寫法,本身就是JS寫法的其實(shí)是不需要轉(zhuǎn)換的,當(dāng)然也不能說的這么絕對(duì),有時(shí)候Babel會(huì)為了兼容性的緣故將高版本的語(yǔ)法翻譯到低版本,這部分不在討論范圍。我們要關(guān)注的其實(shí)是HTMl的處理方式。

比如下面這行代碼:

<div id='name'>Tom and Jerry</div>

通過Babel轉(zhuǎn)換后生成的代碼是:

React.createElement("div", {
   id: "name"}, "Tom and Jerry");

HTML語(yǔ)法轉(zhuǎn)變成了JS語(yǔ)法,簡(jiǎn)單來說,我們所寫的JSX最終變成了JS。

我們寫一個(gè)復(fù)雜點(diǎn)的例子:

<div class='wrapper' id='id_wrapper'>
   <span>Tom</span>
   <span>Jerry</span></div>React.createElement("div", {
   class: "wrapper",
   id: "id_wrapper"
}, React.createElement("span", null, "Tom"), React.createElement("span", null, "Jerry"));

轉(zhuǎn)換規(guī)則是比較簡(jiǎn)單的,React.createElement的第一個(gè)參數(shù)是節(jié)點(diǎn)類型;第二個(gè)參數(shù)是該節(jié)點(diǎn)的屬性,以key:value的形式作為一個(gè)對(duì)象,后面的所有參數(shù)都是該節(jié)點(diǎn)的子節(jié)點(diǎn)。

需要注意的是,在JSX語(yǔ)法中,我們不僅有原生的HTML節(jié)點(diǎn),還有大量的自定義組件,比如:

function Comp() {
   return '<div>Tom and Jerry</div>'
}

<Comp></Comp>
function Comp() {
   return '<div>Tom and Jerry</div>';
}

React.createElement(Comp, null);

可以看出,React.createElement的第一個(gè)參數(shù)變成了一個(gè)變量,而不是一個(gè)字符串,嘗試將函數(shù)Comp首字母小寫:

function comp() {
   return '<div>Tom and Jerry</div>'
}

<comp></comp>
function comp() {
   return '<div>Tom and Jerry</div>';
}

React.createElement("comp", null);

React.createElement的第一個(gè)參數(shù)又變成了一個(gè)字符串。
這也就是我們?cè)赗eact中寫組件的時(shí)候,為什么會(huì)要求首字母大寫的原因,Babel在編譯的時(shí)候會(huì)將首字母小寫的組件視為原生的HTMl節(jié)點(diǎn)進(jìn)行處理,如果我們將自定義組件首字母小寫,后續(xù)的程序?qū)o法識(shí)別這個(gè)組件,最終會(huì)報(bào)錯(cuò)。

ReactElement

通過Babel編譯后的JS代碼,頻繁出現(xiàn)React.createElement這個(gè)函數(shù)。這個(gè)函數(shù)的返回值就是ReactElement,通過上面的示例可以看出,React.createElement函數(shù)的入?yún)⒂腥齻€(gè),或者說三類。

  • type  
    type指代這個(gè)ReactElement的類型。  

    • 字符串比如div,p代表原生DOM,稱為HostComponent

    • Class類型是我們繼承自Component或者PureComponent的組件,稱為ClassComponent

    • 方法就是functional Component

    • 原生提供的Fragment、AsyncMode等是Symbol,會(huì)被特殊處理

  • config  
    參照上面Babel編譯后的代碼,所有節(jié)點(diǎn)的屬性都會(huì)以Key:Value的形式放到config對(duì)象中。

  • children
    子節(jié)點(diǎn)不止會(huì)有一個(gè),所以children不只有一個(gè),從第二個(gè)參數(shù)以后的所有參數(shù)都是children,它是一個(gè)數(shù)組。

ReactElement的結(jié)構(gòu)是這樣的

const element = {
   // This tag allows us to uniquely identify this as a React Element    $$typeof: REACT_ELEMENT_TYPE,

   // Built-in properties that belong on the element    type: type,
   key: key,
   ref: ref,
   props: props,

   // Record the component responsible for creating this element.    _owner: owner,
 };

它就是一個(gè)簡(jiǎn)單的對(duì)象,為了看清楚這個(gè)對(duì)象的創(chuàng)建規(guī)則,我們舉個(gè)例子。 首先是我們寫的JSX:

<div class='class_name' id='id_name' key='key_name' ref='ref_name'>
   <span>Tom</span>
   <span>Jerry</span>
</div>

它會(huì)被Babel編譯為:

React.createElement("div", {
   class: "class_name",
   id: "id_name",
   key: "key_name",
   ref: "ref_name"}, React.createElement("span", null, "Tom"), React.createElement("span", null, "Jerry"));

它會(huì)生成這樣一個(gè)Element

{
   $$typeof: REACT_ELEMENT_TYPE,
   type:'div',
   key: 'key_name',
   ref: "ref_name",
   props: {
       class: "class_name",
       id: "id_name",
       children: [
           React.createElement("span", null, "Tom"),
           React.createElement("span", null, "Jerry")
       ]
   }
    _owner: ReactCurrentOwner.current,}
  • $$typeof 是一個(gè)常量,所有通過React.createElement生成的元素都有這個(gè)值。一般使用 React 的組件都是掛到父組件的 this.props.children 上面,但是也有例外,比如要實(shí)現(xiàn)一個(gè)模態(tài)框,就需要將模態(tài)框掛載到body節(jié)點(diǎn)下,這個(gè)時(shí)候需要使用ReactDOM.createPortals(child, container)這個(gè)函數(shù)實(shí)現(xiàn),這個(gè)函數(shù)生成的$$typeof值就是REACT_PORTAL_TYPE。

  • type指代這個(gè)ReactElement的類型

  • key和ref都是從config對(duì)象中找到的特殊配置,將其單獨(dú)抽取出來,放在ReactElement下

  • props包含了兩部分,第一部分是去除了key和ref的config,第二部分是children數(shù)組,數(shù)組的成員也是通過React.createElement生成的對(duì)象,示例中省略了這個(gè)步驟。

  • _owner在16.7的版本上是Fiber,F(xiàn)iber是react16+版本的核心,暫時(shí)不做深究。

“react element指的是什么”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI