本篇主要的介紹了關於reactjs出現的一些問題,指出了現在用reactjs的一些弊端,有興趣的同學可以進來看看這篇文章
去年4 月,我第一次在某個客戶的專案中接觸ReactJS 。
我發現ReactJS要比我以前用過的AngularJS簡單很多,它提供了響應式的資料綁定功能,把資料映射到網頁上,使我可以輕鬆實現互動簡單的網站。
然而,隨著我越來越深入的使用ReactJS,我發現用ReactJS編寫互動複雜的網頁很困難。我希望有一種方式,能夠像ReactJS一樣簡單解決簡單問題。 此外,還要能簡單解決複雜問題。
於是我把ReactJS用Scala重新寫了一個。程式碼量從近三萬行降到了一千多行。
用這個框架實作的TodoMVC應用,只用了154行程式碼。而用ReactJS實作相同功能的TodoMVC,則需要488行程式碼。
下圖是用Binding.scala實作的TodoMVC應用。
這個框架就是Binding.scala。
ReactJS中的最小複用單位是元件。 ReactJS的元件比AngularJS的Controller和View 輕量一點。每個元件只需要前端開發者提供一個 render
函數,並將 props
和 state
映射成網頁元件。
這樣的輕量級元件在渲染簡單靜態頁面時很好用, 但是如果頁面有交互,就必須在元件間傳遞回調函數來處理事件。
我將在《More than React(二)元件對複用性有害? 》中以原生DHTML API、ReactJS和Binding.scala實作同一個需要重複使用的頁面,介紹Binding.scala如何簡單實作、簡單重複使用複雜的互動邏輯。
ReactJS的頁面渲染演算法是虛擬DOM差量演算法。
開發者需提供 render
函數,依據 props
與 state
產生虛擬
DOM。接著ReactJS 框架根據 render
傳回的虛擬DOM 建立相同結構的真實DOM.
每當 state
變更時,ReacJS 框架重新呼叫 render
函數,取得新的虛擬
DOM 。然後,框架會比較上次產生的虛擬 DOM 和新的虛擬 DOM 有哪些差異,然後把差異應用在真實DOM。
這樣做有兩大缺點:
每次 state
更改,render
函數都要產生完整的虛擬
DOM. 就算 state
改動很小,render
函數也會完整計算一次。如果 render
函數很複雜,這個過程就白白浪費了許多運算資源。
ReactJS框架比較虛擬DOM差異的過程,既慢又容易出錯。例如,假如你想要在某個 <ul></ul>
列表的頂部插入一項 <li>
,那麼ReactJS框架會誤以為你修改了 的每一項
<li>
,然後在尾部插入了一個 <li>
。
這是因為ReactJS收到的新舊兩個虛擬DOM之間相互獨立,ReactJS並不知道資料來源發生了什麼操作,只能根據新舊兩個虛擬DOM來猜測需要執行的操作。自動的猜測演算法既不準又慢,必須要前端開發者手動提供 key
屬性、shouldComponentUpdate
方法、componentDidUpdate
方法或 componentWillUpdate
# 等方法才能幫助
ReactJS 框架猜對。
我將在《More than React(三)虛擬DOM已死? 》中比較ReactJS、AngularJS和Binding.scala渲染機制,介紹簡單效能高的Binding.scala精確資料綁定機制。
ReactJS支援用JSX編寫HTML模板。
理論上,前端工程師只要把靜態HTML原型複製到JSX原始檔中, 增加一些變數取代程式碼, 就能改造成動態頁面。理論上這種做法要比Cycle.js、Widok、ScalaTags等框架更適合重複使用設計師提供的HTML原型。
不幸的是,ReactJS對HTML的支援殘缺不全。開發者必須手動把class
和for
屬性替換成className
和htmlFor
,還要把內聯的style
樣式從CSS語法改成JSON語法,程式碼才能運作。
這種開發方式下,前端工程師雖然可以把HTML原型複製貼到程式碼中,但還需要大量改造才能實際運作。比Cycle.js、Widok、或、ScalaTags省不了太多事。
除此之外,ReactJS也提供了propTypes
機制校驗虛擬DOM的合法性。然而,這機制也漏洞百出。即使指定了propTypes
,ReactJS也無法在編譯前提前發現錯誤。只有測試覆蓋率很高的項目時才能在每個元件使用其他元件時進行校驗。
即使測試覆蓋率很高,propTypes
仍舊無法偵測出拼錯的屬性名,如果你把onClick
寫成了onclick
,
ReactJS不會報錯,往往導致開發者額外花費大量時間來排除一個很簡單的bug。 (想看更多就到PHP中文網React參考手冊欄位中學習)
我將在《More than React(四)HTML也可以編譯? 》中比較ReactJS和Binding.scala的HTML模板,介紹Binding.scala如何在完整支援XHTML語法的同時靜態檢查語法錯誤和語意錯誤。
ReactJS從伺服器載入資料時的架構可以看成MVVM(Model–View–ViewModel)模式。前端工程師需要寫一個資料庫存取層當Model,把ReactJS的state
當做ViewModel,而render
當做View。
Model負責存取資料庫並把資料設定到state
(即View Model)上,可以用Promise和fetch API實作。然後,render
,也就是View,負責把View
Model渲染到頁面上。
在這整套流程中,前端程式設計師需要編寫大量閉包組成的非同步流程, 設定、存取狀態的程式碼五零四散, 一不小心就會bug叢生,就算小心翼翼的處理各種非同步事件,也會導致程式變得複雜,既難調試,又難維護。
我將在《More than React(五)為什麼別用非同步程式設計? 》中比較ReactJS和Binding.scala的數據同步模型,介紹Binding.scala如何自動同步伺服器數據,避免手動非同步程式設計。
儘管Binding.scala初看上去很像ReactJS, 但隱藏在Binding.scala背後的機制更簡單、更通用,與ReactJS和Widok截然不同。
所以,透過簡化概念,Binding.scala靈活性更強,能用通用的方式解決ReactJS解決不了的複雜問題。
例如,除了上述四個面向以外,ReactJS的狀態管理也是老大難問題,如果引入Redux或react-router這樣的第三方函式庫來處理狀態,會導致架構變複雜,分層變多,程式碼繞來繞去。而Binding.scala可以用和頁面渲染一樣的資料綁定機制描述複雜的狀態,不需要任何第三方函式庫,就能提供伺服器通訊、狀態管理和網址分送的功能。
以下表格中列出了上述Binding.scala和ReactJS的功能差異:
Binding.scala | ReactJS | ||
---|---|---|---|
## | Binding.scala | ReactJS | |
復用性 | 最小復用單位 | ||
元件 | 重複使用難度 | #不論互動內容或靜態內容都容易重複使用 | |
#頁面渲染演算法 | 演算法 | ||
虛擬DOM |
效能 ####高#####低###########正確性######自動保證正確性######需要開發者手動設定 ###key### 屬性,不然複雜的頁面會錯亂。 |
||
HTML 範本 | 語法 | Scala XML 字面量 | JSX |
是否支援HTML 或XHTML 語法 | 完整支援XHTML | 殘缺支援。正常的 XHTML 無法編譯。開發者必須手動把 class 和 for 屬性替換成 className 和 htmlFor ,還要把內聯的 style 樣式從
CSS 語法改成 JSON 語法。 |
|
如何校驗範本語法 | 自動編譯時校驗 | #在執行時透過 propTypes 校驗但無法偵測簡單的拼字錯誤。 |
|
伺服器通訊 | 機制 | 自動遠端資料綁定 | MVVM 非同步程式設計 |
實作難度 | 簡單 | 複雜 | |
#其他 | 如何分派網址或錨點連結 | 支援把網址當成普通的綁定變數來用,無需第三方函式庫。 | 不支持,需要第三方函式庫react-router |
功能完備性 | 完整的前端開發解決方案 | 本身只包含視圖部分功能。需要額外掌握 react-router 、 Redux 等第三方函式庫才能實現完整的前端專案。 | |
學習曲線 | API 簡單,對沒用過 Scala 的人來說也很好懂 | 上手快。但功能太弱導致後期學習第三方函式庫時曲線陡峭。 |
兩個多月前,我在Scala.js的論壇上發布Binding.scala時,當時Scala.js社群最受歡迎的響應式前端程式框架是Widok。 Tim Nieradzik是Widok的作者。他在看到我發布的框架後,稱讚這個框架是Scala.js社群最有前途的 HTML 5渲染框架。
他是對的,兩個月後,現在Binding.scala已經成為Scala.js社群最受歡迎的響應式前端程式框架。
Awesome Scala網站比較了Scala的響應式前端程式框架,Binding.scala的活躍程度和流行度都比Udash、Widok等其他框架要高。
這篇文章到這就結束了(想看更多就到PHP中文網React使用手冊欄位中學習),有問題的可以在下方留言提問。
以上是ReactJS的問題有哪些? reactjs問題的總結的詳細內容。更多資訊請關注PHP中文網其他相關文章!