可以少去理解一些不必要的概念,而多去思考為什麼會有這樣的東西,它解決了什麼問題,或者它的運行機制是什麼? React 1. React 起源和發展(是什麼?) React 是用於構建用戶界面的 JavaScript 庫,起源於 Facebook 的內部項目,該公司對市場上所有 JavaScript ...
可以少去理解一些不必要的概念,而多去思考為什麼會有這樣的東西,它解決了什麼問題,或者它的運行機制是什麼?
React
1. React 起源和發展(是什麼?)
React 是用於構建用戶界面的 JavaScript 庫,起源於 Facebook 的內部項目,該公司對市場上所有 JavaScript MVC 框架都不滿意,決定自行開發一套,用於架設 Instagram 的網站。於2013年5月開源。
React 與傳統 MVC 的關係:
React 並不是一個完整的框架,最多認為是 MVC 中的 V (View),即 React 一般被用來作為 MVC 中的 V 層。做為 V 層構建用戶 UI 的庫,可以簡單的理解為,React 將頁面分成了各個獨立的小塊,每一個小快就是一個組件,這些組件之間可以組合、嵌套,就成了我們的頁面。
它不依賴其他任何的庫,在開發中,可以與任何其他的庫集成使用,包括 Jquery。React 的思想非常獨特,性能出眾,可以寫出重覆代碼少,邏輯清晰的前端代碼。它可以在瀏覽器端運行,也可以通過 nodejs 在服務端渲染。
2. React 的特性
-
聲明式設計:React 採用聲明範式,可以輕鬆描述應用。
React 使創建互動式 UI 變得輕而易舉。為你應用的每一個狀態設計簡潔的視圖,當數據變動時 React 能高效更新並渲染合適的組件。以聲明式編寫 UI,可以讓你的代碼更加可靠,且方便調試。
-
高效(虛擬 DOM):React 通過對 DOM 的模擬使用了虛擬 DOM,可以最大限度地減少與真實 DOM 的交互。
-
靈活:React 不依賴其他任何的庫,在開發中 React 可以與已知的庫或框架很好地配合。
-
組件化:通過 React 構建組件,使得代碼更加容易得到復用(復用復用復用),能夠很好的應用在大項目的開發中。
構建管理自身狀態的封裝組件,然後對其組合以構成複雜的 UI。由於組件邏輯使用 JavaScript 編寫而非模板,因此你可以輕鬆地在應用中傳遞數據,並保持狀態與 DOM 分離。
-
單向響應的數據流:React 實現了單向響應的數據流,從而減少了重覆代碼,這也是它為什麼比傳統數據綁定更簡單。
單向數據流,數據流方向是由從上到下(父到子)的,如果下麵子組件數據發生改變(更新)了,要從子組件發送到父組件,父組件更新完了之後再次傳遞給子組件(也就是說子組件數據更新後,需要父組件重新的給它流入一遍),這個時候父子組件都可以使用這個數據。
比如說:老闆下達任務給下屬,然後下屬執行。 如果此時下屬有個想法(比如修改個某某數據),這時需要請示領導,如果領導同意了,那麼下屬得到新的命令再去執行。好處就是,所有的主動權都在頂層組件,下麵所有的變動上面都知道。如果什麼事低下自己決定,直接修改完,告訴上面。出問題調查起來麻煩,不知道上面還是下麵出了問題。
-
JSX: JSX 是 JavaScript 語法的擴展。React 開發不一定使用 JSX ,但我們建議使用它。
React 的語法是 JSX,通過使用這種語法,可以在 React 代碼中直接混合使用 js 和 html、css 來編寫組件代碼,這樣代碼的邏輯就非常清晰,當然也意味著,需要將 jsx 代碼編譯成普通的 javascript 代碼,才能在瀏覽器中運行, 這個過程讓 React 中的處理器去解析 JSX 就行了。
-
一次學習,跨平臺編寫:
無論你現在使用什麼技術棧,在無需重寫現有代碼的前提下,通過引入 React 來開發新功能。React 還可以使用 Node 進行伺服器渲染,或使用 React Native 開發原生移動應用。
3. React 的缺點
並不是一個單獨完整的框架,React 是目標是 UI 組件,通常可以和其它框架組合使用,目前並不適合單獨做一個完整的框架。
4. 什麼是虛擬 DOM?
4.1)傳統 DOM 更新
真實頁面對應一個 DOM 樹,在傳統的開發中,每次需要修改、更新頁面時,都需要手動直接操作 DOM 來進行更新。
4.2)虛擬 DOM
DOM 操作非常昂貴。我們都知道在前端開發中,性能消耗最大的就是 DOM 操作,而且這部分代碼會讓整體項目的代碼變得難以維護。React 把真實的 DOM 樹、數據轉換成 JavaScript 對象,也就是 Virtual DOM(虛擬 DOM、VDOM、vnode)。也就是說在 React 中用 JS 對象來描述虛擬 DOM 樹。
比如在 React 中,render 執行的結果得到的並不是真正的 DOM 節點,而是 Virtual DOM, 即僅僅是輕量級的 JavaScript 對象 。
虛擬 DOM 原理:
React 會基於真實 DOM 和數據創建兩條虛擬 DOM ,用 DIFF 演算法以最小的代價對比(DIFF)出兩個虛擬 DOM 數據節點是不是有改變。從而只選擇將需要修改的部分給標記起來,做一個補丁,真正更新到真實的 DOM 中。
不動其他 DOM 只會影響改變的 DOM,其他 DOM 節點不需要重新創建的,只需要調整位置。
React 虛擬 DOM 核心思想:
對複雜的文檔 DOM 結構,提供一種方便的工具,進行最小化地 DOM 操作。這句話,也許過於抽象,卻基本概況了虛擬 DOM 的設計思想。
虛擬 DOM 總結:
虛擬 DOM 是 React 的一大亮點,具有 batching(批處理)和高效的 Diff 演算法。這讓我們可以無需擔心性能問題而“毫無顧忌”的隨時“刷新”整個頁面,由虛擬 DOM 來確保只對界面上真正變化的部分進行實際的 DOM 操作。在實際開發中基本無需關心虛擬 DOM 是如何運作的,但是理解其運行機制不僅有助於更好的理解 React 組件的生命周期,而且對於進一步優化 React 程式也會有很大幫助。
虛擬 DOM 實例:
React 會基於真實 DOM 和數據創建兩條虛擬 DOM,這裡就可以做一個對比:前後兩條沒有做出改變,中間少了一條,這時候給他標記起來,做一個補丁 patch(s) ,真正更新到真實的 DOM 中。
// 原始基礎數據:[111, 222, 333],基於基礎數據創建出來的虛擬 DOM 如下:
{
{
type:"li",
text:"111",
},
{
type:"li",
text:"222",
},
{
type:"li",
text:"333",
},
}
// 修改後的數據:[111, 333],基於新的基礎數據創建出來的虛擬 DOM 如下:
{
{
type:"li",
text:"111",
},
{
type:"li",
text:"333",
},
}
4.3)DOM 直接操作對性能的影響
DOM 直接操作將導致迴流重排嚴重影響性能,比如減少的 Dom 刪掉,下麵的 Dom 需要往上移,引發文檔的重排,迴流的問題。頻繁改變 DOM 就會導致迴流現象,迴流就是重新排列下它的順序,然後重新渲染一遍,就會影響我們的性能。
Umi
Umi,中文可發音為烏米,是可擴展的企業級前端應用框架。Umi 以路由為基礎的,同時支持配置式路由和約定式路由,保證路由的功能完備,並以此進行功能擴展。然後配以生命周期完善的插件體系,覆蓋從源碼到構建產物的每個生命周期,支持各種功能擴展和業務需求。其次 Umi 本身是基於 React 構建的。
create-react-app 是基於 webpack 的打包層方案,包含 build、dev、lint 等,他在打包層把體驗做到了極致,但是不包含路由,不是框架,也不支持配置。所以,如果大家想基於他修改部分配置,或者希望在打包層之外也做技術收斂時,就會遇到困難。
React Native
React 是用於構建用戶界面的 JavaScript 庫,是基於瀏覽器的。React Native 可以基於目前大熱的開源 JavaScript 庫 React.js 來開發 iOS 和 Android 原生 App。
React 和 React Native 的區別:
1)框架作用的平臺不同
RN 是由 React 衍生出來的,兩種框架都是用 JSX 開發語法,但是 RN 是用來開發真正基於原生渲染的 iOS 和 Andriod 移動應用的 JS 框架,而React 是將瀏覽器作為渲染平臺。
2)工作原理的差別
Virtual DOM 是介於開發者描述的視圖與實際在頁面上渲染的視圖之間。在瀏覽器上如果想渲染出來可交互的用戶界面,開發者必須操作瀏覽器的文檔對象(document object model),Virtual DOM 的出現,就是為了節省這部分操作所消耗的性能。但是 Virtual DOM 的巨大潛力,是在於這個抽象層,可以帶來很多可能性。
React Native 的工作原理,就是調用 Objective-C 的 API 去渲染 iOS 組件,調用 Java API 去渲染 Android 組件,而不是渲染到 DOM 上。橋接使得 React 可調用宿主平臺開放的 UI 組件,React 組件通過 render 方法返回了描述界面的標記代碼。如果是 Web 平臺,React 最終把標記代碼解析成瀏覽器的 DOM;而在 React Native 中,標記代碼會解析成特定平臺的組件,例如會表現成 iOS 平臺上的 UIView。
3)渲染周期
React 的渲染周期開始於 React 組件掛載到 DOM 之後,接著 React 進入渲染周期並根據需要渲染組件。在渲染階段,React 將開發者在 return 中返回的 HTML 標記直接按需渲染到頁面上。
React Native 生命周期與 React 基本相同,在渲染上因為 React Native 依賴於橋接,並不在 UI 主線程運行,它可以在不影響用戶體驗的前提下執行這些非同步調用。
4)創建組件
當編寫 Web 環境的 React 的時候,視圖最終需要渲染成普通的 HTML 元素;而在 React Native 中,所有元素都會被平臺指定的組件替換,例如在 iOS 中,組件被渲染成 UIView,而在 Android 平臺,會被渲染成 View。UI 元素均為 React 的(原生的)組件,而不是基礎的 html 元素,因此在使用每一個組件的時候,都需要顯式的導入。
5)原生的樣式
在 Web 中,使用 CSS 樣式為 React 組件添加樣式已經是開發過程中不可獲取的一部分了。React 通常不影響我們編寫 CSS 的方式,並且它確實讓樣式的動態創建更加容易(通過 state 和 props),除此之外,React 基本上不關心我們如何處理樣式的。
非 Web 平臺上有大量的方法來處理佈局和樣式,我們使用 React Native 時,只需要用一種標準的方法來處理樣式,React 和宿主平臺之間的橋接包含了一個縮減版 CSS 子集的實現,這個 CSS 子集主要通過 flexbox 進行佈局,做到了儘量簡化,而不是去實現所有的 CSS 規則。有別於 Web 平臺,CSS 的支持程度因瀏覽器而不同,React Native 則做到了樣式規則的一致。
6)宿主平臺 Api
使用 Web 環境的 React 與 React Native 最大的不同,在於宿主平臺的 Api。
在 Web 中,我們通常要處理採納標準的不一致和碎片化所引起的問題,並且大多數瀏覽器只支持部分核心的特性。然而在 React Native 中,平臺特定的 Api 在提供優秀原生的用戶體驗方面發揮了巨大的作用。當然,要考慮的方面還有很多。Api 囊括了許多功能,從數據存儲到地理服務,以及操控硬體設備(如攝像頭)等。非常規平臺上的 Api 會更有趣,例如,React Native 和虛擬現實頭盔之間的 API 會是什麼樣的呢?
預設情況下,iOS 和 Android 版本的 React Native 支持許多常用的特性,甚至可以支持任何非同步的本地 Api。React Native 讓宿主平臺 Api 的使用變得更加簡單和直觀,你可以在其中自由地試驗。同時,務必思考一下怎樣做才符合目標平臺的體驗,併在心裡設計好交互過程。毋庸置疑,React Native 的橋接不可能暴露宿主平臺全部的 Api。
如果你需要使用一個未支持的特性,完全可以自己動手添加到 React Native 中。另外,如果其他人已經集成,那就更好了,所以應該及時查看社區中的實現。值得註意的是,使用平臺 Api 也會對代碼復用有幫助。同時,實現平臺特定功能的 React 組件也是平臺特定的。
隔離和封裝這些組件將會給你的應用帶來更大的靈活性。當然,這對你開發 Web 應用同樣奏效,如果你想共用 React 和 React Native 的代碼,請記住像 DOM 這樣的 API 在 React Native 中並不存在。