本篇主要的介紹了關於reactjs出現的一些問題,指出了現在用reactjs的一些弊端,有興趣的同學可以進來看看這篇文章
背景介紹
去年4 月,我第一次在某個客戶的專案中接觸ReactJS 。
我發現ReactJS要比我以前用過的AngularJS簡單很多,它提供了響應式的資料綁定功能,把資料映射到網頁上,使我可以輕鬆實現互動簡單的網站。
然而,隨著我越來越深入的使用ReactJS,我發現用ReactJS編寫互動複雜的網頁很困難。我希望有一種方式,能夠像ReactJS一樣簡單解決簡單問題。 此外,還要能簡單解決複雜問題。
於是我把ReactJS用Scala重新寫了一個。程式碼量從近三萬行降到了一千多行。
用這個框架實作的TodoMVC應用,只用了154行程式碼。而用ReactJS實作相同功能的TodoMVC,則需要488行程式碼。
下圖是用Binding.scala實作的TodoMVC應用。
這個框架就是Binding.scala。
問題一:ReactJS元件難以在複雜互動頁面中重複使用
ReactJS中的最小複用單位是元件。 ReactJS的元件比AngularJS的Controller和View 輕量一點。每個元件只需要前端開發者提供一個 render
函數,並將 props
和 state
映射成網頁元件。
這樣的輕量級元件在渲染簡單靜態頁面時很好用, 但是如果頁面有交互,就必須在元件間傳遞回調函數來處理事件。
我將在《More than React(二)元件對複用性有害? 》中以原生DHTML API、ReactJS和Binding.scala實作同一個需要重複使用的頁面,介紹Binding.scala如何簡單實作、簡單重複使用複雜的互動邏輯。
問題二:ReactJS的虛擬DOM 演算法又慢又不準
ReactJS的頁面渲染演算法是虛擬DOM差量演算法。
開發者需提供 render
函數,依據 props
與 state
產生虛擬
DOM。接著ReactJS 框架根據 render
傳回的虛擬DOM 建立相同結構的真實DOM.
每當 state
變更時,ReacJS 框架重新呼叫 render
函數,取得新的虛擬
DOM 。然後,框架會比較上次產生的虛擬 DOM 和新的虛擬 DOM 有哪些差異,然後把差異應用在真實DOM。
這樣做有兩大缺點:
-
<li>
每次 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的HTML模板功能既不完備、也不健全
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與伺服器通訊時需要複雜的非同步程式設計
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中文網其他相關文章!

JavaScript在現實世界中的應用包括前端和後端開發。 1)通過構建TODO列表應用展示前端應用,涉及DOM操作和事件處理。 2)通過Node.js和Express構建RESTfulAPI展示後端應用。

JavaScript在Web開發中的主要用途包括客戶端交互、表單驗證和異步通信。 1)通過DOM操作實現動態內容更新和用戶交互;2)在用戶提交數據前進行客戶端驗證,提高用戶體驗;3)通過AJAX技術實現與服務器的無刷新通信。

理解JavaScript引擎內部工作原理對開發者重要,因為它能幫助編寫更高效的代碼並理解性能瓶頸和優化策略。 1)引擎的工作流程包括解析、編譯和執行三個階段;2)執行過程中,引擎會進行動態優化,如內聯緩存和隱藏類;3)最佳實踐包括避免全局變量、優化循環、使用const和let,以及避免過度使用閉包。

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

Python和JavaScript在社區、庫和資源方面的對比各有優劣。 1)Python社區友好,適合初學者,但前端開發資源不如JavaScript豐富。 2)Python在數據科學和機器學習庫方面強大,JavaScript則在前端開發庫和框架上更勝一籌。 3)兩者的學習資源都豐富,但Python適合從官方文檔開始,JavaScript則以MDNWebDocs為佳。選擇應基於項目需求和個人興趣。

從C/C 轉向JavaScript需要適應動態類型、垃圾回收和異步編程等特點。 1)C/C 是靜態類型語言,需手動管理內存,而JavaScript是動態類型,垃圾回收自動處理。 2)C/C 需編譯成機器碼,JavaScript則為解釋型語言。 3)JavaScript引入閉包、原型鍊和Promise等概念,增強了靈活性和異步編程能力。

不同JavaScript引擎在解析和執行JavaScript代碼時,效果會有所不同,因為每個引擎的實現原理和優化策略各有差異。 1.詞法分析:將源碼轉換為詞法單元。 2.語法分析:生成抽象語法樹。 3.優化和編譯:通過JIT編譯器生成機器碼。 4.執行:運行機器碼。 V8引擎通過即時編譯和隱藏類優化,SpiderMonkey使用類型推斷系統,導致在相同代碼上的性能表現不同。

JavaScript在現實世界中的應用包括服務器端編程、移動應用開發和物聯網控制:1.通過Node.js實現服務器端編程,適用於高並發請求處理。 2.通過ReactNative進行移動應用開發,支持跨平台部署。 3.通過Johnny-Five庫用於物聯網設備控制,適用於硬件交互。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

SublimeText3漢化版
中文版,非常好用

MinGW - Minimalist GNU for Windows
這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

Dreamweaver CS6
視覺化網頁開發工具

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

禪工作室 13.0.1
強大的PHP整合開發環境