摘要:元素和組件實例都不表示真實元素。我希望這篇文章能夠幫助你理清這些術語參考資料翻譯成支撐實例來自于理解中方法創建組件的聲明式編程和命令式編程的比較對循環提示增加的研究精髓之一算法
本篇為譯文,原文出處:React Elements vs React Components vs Component Backing Instances
許多人可能聽說過 Facebook 的 React 庫,并在自己的工作或項目中使用它。React 是非常流行的,使開發用戶界面變得簡單且符合聲明式編程(譯者注:聲明式編程可以參考聲明式編程和命令式編程的比較)。
正如題目所示,React 有幾個概念遍及其文檔,這(幾個概念)可能會讓新React用戶困惑。例如,你在 Glossary、Top-Level API 和 Explanation on Refs 這幾章中檢索 “React Element”、“React Component” 和 “Component Backing Instance”,你會發現這幾個術語遍及各處,已經是 React 的絕對的核心。
這篇文章不是一篇 React 的教程,更多的是分享我最近學習 React 而得到的一些(知識)。因此,這篇文章是針對之前已經涉獵過 React 的人們,我會假設你已經熟悉 React 一些核心概念和語法。
React元素是什么?React 元素這個概念對于 React 來說很重要,但是我堅信一點,因為使用 React 和 JSX 來構建用戶界面過于簡單,從而導致可能在最初錯過這個概念。如果你之前用過 React + JSX,毫無疑問的說,在你的 JS 文件中書寫類 HTML 語法更加符合你的習慣(譯者注:Habit is second nature. 習慣成自然)。在這種(書寫類HTML語法)假象之下,JSX 語法實際上被編譯成特殊的函數調用 — React.createElement()。 猜猜 React.createElement()會產生什么?耶,你猜對了,就是 React 元素。讓我們看一個轉換過程的例子:
// 使用 JSX 語法 var helloWorld =Hello World!; // 然后是 JSX 被編譯成 JavaScript 后的結果 var helloWorld = React.createElement( "div", null, "Hello World!" ); // 再是處理成 JavaScript 簡單對象后看起來類似這樣 var helloWorld = { key: null, props: { children: "Hello World!" // more stuff in here }, ref: null, type: "div" // more stuff in here };
React 元素是由一些屬性(properties)構成的 JavaScript 簡單對象(plain old JavaScript objects,譯者注:關于更多解釋可以看 Plain Old JavaScript,What is a plainObject in JavaScript?):
key - 屬性 key 是用來在一組相同類型的 React 元素構成的 Array 中標識唯一特定 React 元素。你不必提供一個值給它(譯者注:在新版 React 中,如果在循環一組相同類型的 React 元素時不指定 key,會報一個 warning 錯誤,具體可以參考 React 對循環 warning 提示增加 key 的研究),但是如果你給 key 提供一個值,React 將能夠進行優化,使重新渲染過程更高效。
props - 屬性props 恰恰是你所認為的: 它是向下傳遞給子組件(child components)的所有 props 和 values 的映射(集合)。
ref - 屬性ref 用來訪問與這個 React 元素相關聯的經過(瀏覽器或渲染引擎)渲染處理后的底層 DOM 元素。
type - 屬性type 將是兩種格式之一,表示任何有效的 HTML 元素的(名稱)字符串 或 指向 React 組件類的引用。
此時, 了解每個屬性所有細節并不重要。最大的收獲在于,React 元素僅僅是 JavaScript 簡單對象(plain old JavaScript objects),用來描述組件的 HTML 應是怎樣的結構,這個對象上不包含任何方法(Methods),僅僅只有數據。
通過之前 helloWorld React 元素的例子告訴你,helloWorld表示一個子節點為“Hello World!”文本的 div 標簽。即使你創建了一個更復雜的 JSX 例子,生成的 React 元素仍將是一個 JavaScript 對象,配合其他嵌套 React 元素描述 HTML 將是怎樣的結構。如果這讓你感覺熟悉,是因為這正是虛擬 DOM(Virtual DOM)是什么(的解釋) - 它是 DOM 在特定時間段應該是怎樣的結構的描述,通過 React 元素聲明來表示。
React組件是什么?不同于 React 元素,你可能對 React 組件更熟悉一些。如果你曾寫過類似下面例子的代碼,那么你之前已經創建過 React 組件類了:
// 這是一個 React 組件類 class CustomForm extends React.Component { constructor(props) { super(props); this.state = { inputText: "Willson" }; this.handleInputChange = this.handleInputChange.bind(this); } handleInputChange(e) { const inputText = e.target.value; this.setState({ inputText }); } render() { return (); } } /* * 我假設你有可用的 React 和 ReactDom,以及 * 一個 id 為 "root" 的 HTML 元素 * ReactDOM.render() 的返回值是組件實例 */ var componentInstance = ReactDOM.render(Hello, {this.state.inputText}
, document.getElementById("root"));
上面的例子是用 ES2015 新的 Class 語法寫的,但它幾乎相當于使用 React.createClass()。你也許熟悉編寫這些組件類,但重要的是(React文檔中所述的)React 組件指代的是一個 React 組件類的實例。
假如你熟悉 JavaScript 的話,當你聽到到“實例化一個類”且智商在線時,你可能會考慮使用new操作符。然而,(在 React 中)從不需要你用 new 操作符創建 React 組件。相反的是,你將使用 ReactDOM.render() 把一個 React 元素渲染成一個特定的 DOM 元素,與此同時,ReactDOM.render() 將返回一個 React 組件實例。
從 ReactDOM.render() 返回的組件實例可以調用在 React 組件類中定義的方法。反過來想一下會讓你明白,ReactDOM.render() 是 React 為你實例化一個組件的機制。通常, 你不需要訪問組件實例本身, 但我發現在測試 React 組件時, 將組件實例的引用保存下來(對測試)很有幫助。
與 ReactDOM.render() 有關的最后一個有趣的點是,React 在 ReactDOM.render() 時對虛擬 DOM 執行高效的 diff 算法(譯者注: diff 算法延伸閱讀)。如果你記得(上面說的),React 元素表示虛擬 DOM(元素),這意味著 ReactDOM.render() 接收一個虛擬 DOM(元素),將其渲染成一個真實 DOM 元素,返回(React 元素 type 指定的)組件實例。在底層,如果你將相同的React元素類型(帶有可能不同的 props 值)通過 ReactDOM.render() 渲染成相同的 DOM 元素,React 將執行 diff 算法,對 DOM 元素進行僅必須的最小更改。也許令人驚訝的是,它每次返回相同的組件實例 - 除了更新的 prop 和 state 值。
組件支撐實例是什么?前兩節探討了 React 元素和 React 組件實例,這兩個概念都是 DOM 之上的抽象層。 現在我們將討論術語“組件支撐實例”,以及它們自身如何與真實 DOM 元素相關聯。
// 組件類 class CustomForm extends React.Component { constructor(props) { super(props); this.state = { inputText: "Willson" }; this.handleInputChange = this.handleInputChange.bind(this); } handleInputChange(e) { const inputText = e.target.value; this.setState({ inputText }); } render() { return (); } } // 組件實例 var componentInstance = ReactDOM.render(Hello, {this.state.inputText}
, document.getElementById("root")); // DOM 實例 var domInstance = ReactDOM.findDOMNode(componentInstance); // 原文作者這里出了個 Bug,多了一個 D
在前面的實例中,ReactDOM.render() 通過將 React 元素渲染到現有的 DOM 元素中來生成一個組件實例。正如我們已經知道的,組件實例不是真實 DOM 節點。然而,訪問與組件實例關聯的底層 DOM 節點實際上很簡單 - 我們使用 ReactDOM.findDOMNode(),并將組件實例作為其參數傳遞。那么這與“組件支撐實例”術語有什么關系呢?讓我們一臉懵逼的是,React 在其文檔的各處將引用的真實 DOM 節點稱之為組件支撐實例。
總結這3個術語“React 元素”,“React 組件”和“組件支撐實例”是密切相關的。 由于 JSX 語法被轉譯為 React.createElement()調用(譯者注:理解轉譯這個概念可以參考 Compiling Vs Transpiling),最終返回我們稱之為“React 元素”的 JavaScript 簡單對象(plain old JavaScript objects),你可以將 React元素視為基礎構建單元。React 組件實例表示下一個抽象層 - ReactDOM.render() 接收一個 React 元素、引用一個真實 DOM 節點、返回一個 React 組件實例。該實例可以訪問組件類中定義的方法,但是在單元測試之外很少用到這一點。React 元素和 React 組件實例都不表示真實 DOM 元素。渲染組件實例產生的 DOM 元素被稱為組件支撐實例,訪問它的主要方式是使用ReactDOM.findDOMNode()。
我希望這篇文章能夠幫助你理清這些術語!
[參考資料]
Backing Instances 翻譯成 支撐實例 來自于 理解React中es6方法創建組件的this
聲明式編程和命令式編程的比較
React 對循環 warning 提示增加 key 的研究
react精髓之一---diff算法
Compiling Vs Transpiling
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/82673.html
摘要:前端日報精選創建對象從到按鈕元素新屬性等簡介聊聊的設計思想譯漸進增強的布局從浮動到到一個少女心滿滿的例子帶你入門中文原創函數式組件的實踐框架嘗鮮知乎專欄譯知乎專欄周刊技術周刊期知乎專欄布局新舊混合寫法詳解兼容微信組件簡介眾成翻 2017-08-07 前端日報 精選 JavaScript創建對象—從es5到es6HTML5按鈕元素新屬性formaction,formenctype等簡介聊...
摘要:高階組件和高階函數高階組件是編程中的常見模式。您可以將上面例子中的高階函數用函數的方式來重新整理如你所見,這就像是一個高階函數,這個函數接受一個函數,返回一個新的元素。函數式編程范例旨在避免在應用程序中使用狀態。 原文:The functional side of React作者:Andrea Chiarelli譯者:博軒 React 是現在最流行的 JavaScript 庫之一。使用...
摘要:在對比我最近幾個月所用的開發工具后,我發現了一些驚人的東西。永遠不停止使用。將警告未使用的代碼。預檢查使用,,和非常有用。不再需要使用開啟服務器,創建應用程序,并打開瀏覽器。嘗試使用別的東西,立即出現錯誤。 原文:Supercharging Frontend Development with VS Code 作者:zachcodes 過去幾天,為了在開發 GraphQL / Rea...
摘要:我們可以為元素添加屬性然后在回調函數中接受該元素在樹中的句柄,該值會作為回調函數的第一個參數返回。使用最常見的用法就是傳入一個對象。單向數據流,比較有序,有便于管理,它隨著視圖庫的開發而被概念化。 面試中問框架,經常會問到一些原理性的東西,明明一直在用,也知道怎么用, 但面試時卻答不上來,也是挺尷尬的,就干脆把react相關的問題查了下資料,再按自己的理解整理了下這些答案。 reac...
摘要:前端日報精選我是如何實現的在線升級熱更新功能的張鑫旭鑫空間鑫生活翻譯表單的運用第期晉升評審的套路異步編程的四種方式黃博客精選組件設計和分解思考掘金中文譯使登錄頁面變得正確掘金前端從強制開啟壓縮探究插件運行機制掘金個常用的簡 2017-06-28 前端日報 精選 我是如何實現electron的在線升級熱更新功能的? ? 張鑫旭-鑫空間-鑫生活【翻譯】React 表單: Refs 的運用【...
閱讀 1255·2021-11-22 13:54
閱讀 1440·2021-11-22 09:34
閱讀 2721·2021-11-22 09:34
閱讀 4034·2021-10-13 09:39
閱讀 3352·2019-08-26 11:52
閱讀 3376·2019-08-26 11:50
閱讀 1544·2019-08-26 10:56
閱讀 1925·2019-08-26 10:44