react element是「React.createElement」函數的回傳值,即ReactElement;ReactElement的結構是「const element = {Element $$typeof: REACT_ELEMENT_TYPE,key: key,ref: ref,props: props, _owner: owner, };」。
本教學操作環境:Windows10系統、react16.9.0版、Dell G3電腦。
react element什麼意思?
React原始碼| ReactElement
說到ReactElement,不得不提的就是在React中,用來取代JavaScript(JS)的語言,JSX 。
作為React的官方指定語法,JSX允許使用者在JS程式碼中插入HTML程式碼。但是,這種寫法瀏覽器是無法解析的。他們需要一個轉換器,Babel就充當了這樣一個角色,他在JSX程式碼編譯時候將其轉換成JS文件,這樣瀏覽器就能解析了。
怎麼轉換呢,我們知道,JSX有JS和HTMl兩種寫法,本身就是JS寫法的其實是不需要轉換的,當然也不能說的這麼絕對,有時候Babel會為了兼容性的緣故將高版本的語法翻譯到低版本,這部分不在討論範圍。我們要關注的其實是HTMl的處理方式。
例如下面這行程式碼:
<div id='name'>Tom and Jerry</div>
透過Babel轉換後產生的程式碼是:
React.createElement("div", {
id: "name"}, "Tom and Jerry");
HTML語法轉變成了JS文法,簡單來說,我們寫的JSX最後變成了JS。
我們寫一個複雜點的範例:
<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"));
轉換規則是比較簡單的,React.createElement的第一個參數是節點類型;第二個參數是該節點的屬性,以key:value的形式作為一個對象,後面的所有參數都是該節點的子節點。
要注意的是,在JSX語法中,我們不僅有原生的HTML節點,還有大量的自訂元件,例如:
function Comp() {
return '<div>Tom and Jerry</div>'
}
<Comp></Comp>
function Comp() {
return '<div>Tom and Jerry</div>';
}
React.createElement(Comp, null);
可以看出,React.createElement的第一個參數變成了一個變量,而不是一個字串,嘗試將函數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的第一個參數又變成了一個字串。
這也就是我們在React中寫入元件的時候,為什麼會要求首字母大寫的原因,Babel在編譯的時候會將首字母小寫的元件視為原生的HTMl節點進行處理,如果我們將自訂組件首字母小寫,後續的程式將無法辨識這個組件,最終會報錯。
透過Babel編譯後的JS程式碼,頻繁出現React.createElement這個函數。這個函數的回傳值就是ReactElement,透過上面的範例可以看出,React.createElement函數的入參有三個,或者說三類。
type
type指涉這個ReactElement的型別。
字串例如div,p代表原生DOM,稱為HostComponent
Class型別是我們繼承自Component或PureComponent的元件,稱為ClassComponent
方法就是functional Component
參考上面Babel編譯後的程式碼,所有節點的屬性都會以Key:Value的形式放到config物件中。
子節點不只會有一個,所以children不只有一個,從第二個參數以後的所有參數都是children,它是一個陣列。
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, };它就是一個簡單的對象,為了看清楚這個對象的創建規則,我們舉個例子。首先是我們寫的JSX:
<div class='class_name' id='id_name' key='key_name' ref='ref_name'> <span>Tom</span> <span>Jerry</span> </div>它會被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"));它會產生這樣一個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 是一個常數,所有透過React.createElement產生的元素都有這個值。一般使用React 的元件都是掛到父元件的this.props.children 上面,但是也有例外,例如要實作一個模態框,就需要將模態框掛載到body節點下,這個時候需要使用ReactDOM. createPortals(child, container)這個函數實現,這個函數產生的$$typeof值就是REACT_PORTAL_TYPE。
type指涉這個ReactElement的類型
key和ref都是從config物件中找到的特殊配置,將其單獨抽取出來,放在ReactElement下
props包含了兩部分,第一部分是去除了key和ref的config,第二部分是children數組,陣列的成員也是透過React.createElement產生的對象,範例中省略了這個步驟。
_owner在16.7的版本上是Fiber,Fiber是react16 版本的核心,暫時不做深究。
透過這篇文章,我們了解到,JSX中的HTML節點,在Babel的幫助下,轉換為嵌套的ReactElement對象,這些資訊對於後期建構應用的樹結構時非常重要的,而React則透過提供這些類型的數據,來脫離平台的限制。
推薦學習:《react影片教學》
以上是react element什麼意思的詳細內容。更多資訊請關注PHP中文網其他相關文章!