做者:Samer Buna翻譯:瘋狂的技術宅javascript
原文:https://medium.com/edge-coder...html
未經容許嚴禁轉載前端
這道題的答案有點複雜。java
首先要搞清楚 element 和 component 是否是一回事?
從技術上來講,ReactDOM 不會在 DOM 中渲染 React 組件或 React 元素。它渲染由其組件實例支持的 DOM 元素。對於類組件來講這是正確的。可是對於函數組件,ReactDOM 僅渲染 DOM 元素。函數組件沒有實例(能夠經過 this
訪問),所以在使用函數組件時,ReactDOM 會渲染由函數返回的元素所生成的 DOM 元素。react
你須要在這裏理解的是,React 元素不一樣於 DOM 元素。 React 元素只是 HTML 元素、React 組件或它們的混合的「描述」。程序員
好吧,一個更好的面試題可能應該這樣問:當你在JSX中使用 <MyComponent/>
之類的東西時,它是組件、元素仍是實例?面試
這是一個元素,但不是 DOM 元素,而是一個 React元 素。由於任何 JSX 標籤都會被轉換爲 React.createElement
再去調用。算法
可是要想讓 React 繼續使用這個 React 元素的話,必須調用一個函數或從一個類中建立實例。segmentfault
你可能會在一些 React 教程中看到 組件(component)、元素(element) 和 實例(instance) 這些詞。我在這裏混用這些詞是不對的,可是我認爲 React 的初學者須要瞭解它們的區別。 React 官方博客上有一篇文章專門說明這些概念,但我認爲這些內容對於初學者來講還遠遠不夠。數組
如下是這些術語的簡單定義:
this
關鍵字。你不須要手動從類建立實例,只須要記住它就在 React 的內存中便可。最重要的是,ReactDOM 不會在瀏覽器中渲染組件,也不會渲染元素(這裏的術語元素表明 React.createElement
的返回值)。它也不渲染實例。 它只渲染 DOM 元素。
不幸的是,使用術語組件既指模板又指經過模板使用的任何一種實例或者調用,這彷佛是很廣泛的。人們對此感到困惑很正常,這挺痛苦的。
每一個 React 應用都從一個使用 React element 的 render
調用開始。下面以 reactjs.org 官網提供的 HelloMessage
案例做爲例子,我對這個例子稍微作了一些修改,使其具備了函數組件:
const Today = () => ( <div>Today is {new Date().toDateString()}</div> );class HelloMessage extends React.Component { render() { return ( <React.Fragment> <div>Hello {this.props.name}</div> <Today /> </React.Fragment> ); } }ReactDOM.render( <HelloMessage name="Taylor" />, mountNode );
第一個 React 元素是咱們在 ReactDOM.render
調用中開始的元素:
<HelloMessage name="Taylor" /> // 這是 React element
這個 React 元素描述了要渲染的 DOM 樹應該以 HelloMessage
組件和值等於 Taylor
的 prop name
開始。
如今回答問題:HelloMessage
是什麼?
每當 React 元素描述一個 React 組件時(就像上面的 React 元素同樣),React 使用該組件將描述替換爲組件返回的內容。這時它將會爲基於類的組件建立一個實例,並將該實例的引用保留在內存中。它不會爲基於函數的組件建立任何內容。它只是調用它們。
從 HelloMessage
組件返回的是一個描述 React.Fragment
組件的 React 元素。
回答問題: React.Fragment
是什麼?
React 會持續不斷的減小這些組件的未知描述,直到只存在有效的 DOM 節點。 React.Fragment
的描述被翻譯成 2 個React 元素,一個描述 div
,另外一個描述 Today
組件。
回答問題:代碼中的 Today
什麼是?
它調用 Today
函數來找出最後一個問題。 Today
函數返回描述一個 div
的 React 元素。
至此,virtual 樹中包含了全部描述 DOM 節點的 React 元素。 React 經過一致性比較算法找出要在瀏覽器中更新的內容。用組件實例所轉換的樹節點保留修改該實例的能力。