標籤:

React Fire: 現代化的React DOM

React Fire: 現代化的React DOM

來自專欄掘金翻譯計劃67 人贊了文章

今年,React團隊的主要著力點是徹底地改進React。

隨著這項工作越來越接近完成,我們開始考慮React DOM的下一個主要版本會是什麼樣子。有相當多的已知問題,其中一些如果沒有更大的內部更改,就很難進行修復。

我們希望彌補過去的錯誤,這些錯誤導致了無數的後續修復,並造成了大量的技術債務。我們還希望刪除事件系統中的一些代碼,這些代碼實際上從React的第一天起就一直沒有被執行過,這帶來了許多複雜性和捆綁包大小。

我們把這項任務稱為React Fire。

React Fire

React Fire是React DOM的現代化版本。我們的目標是使React更好地與DOM的工作方式保持一致,重新考慮過去導致問題的一些有爭議的決策,並使React更小、更快。

我們希望在將來的React major版本中發布這組更改,因為有些更改是不向前兼容的。但即便是這樣,我們認為這些代價也是值得的。我們在Facebook上有超過5萬個組件來檢驗我們的遷移策略。除了一些有針對性的修復或自動化的代碼之外,我們不能重寫產品代碼。

具體措施

有一些不同的東西構成了我們目前的計劃。我們可能會添加或刪除一些東西,但目前的想法大致如下:

  1. 停止在value屬性中同步輸入值(#11896)。這最初是在React 15.2.0版本通過#6406添加的。這是非常常見的請求,因為人們對DOM的概念模型是,他們在DOM檢查器中看到的值應該與值JSX屬性匹配。但DOM不是這樣工作的。當您鍵入欄位時,瀏覽器不會更新值屬性。React也不應該這麼做。事實證明,這種改變雖然可能有助於一些依賴於CSS選擇器的代碼,但卻導致了一連串的錯誤——其中一些至今仍未修復。這個變化帶來的影響包括:#7179,#8395,#7328,#7233,#11881,#7253,#9584,#9806,#9714,#11534,#11746,#12925。在這一點上,繼續與瀏覽器對抗顯然是不值得的,我們應該恢復它。這個過程的積極部分是由於我們的DOM貢獻者(@nhunzaker, @aweary, @jquense,和@philipp-spiess)的不懈工作,我們現在有了詳細的DOM測試裝置,可以幫助我們避免回歸。
  2. 將事件附加到React根目錄而不是文檔(#2043)。在將React應用程序嵌入到更大的系統中時,將事件處理程序附加到文檔就成了一個問題。Atom編輯器是遇到這種情況的首批案例之一。任何大的網站最終也會發展出非常複雜的邊緣案例,與停止傳播、與非反應代碼交互或跨反應根交互(#8693、#8117、#12518)。我們還希望將事件急切地附加到每個根上,以便在更新期間可以做更少的運行時檢查。
  3. 將onChange更名到onInput,不要為非受控組件修復它(#9657)。有關詳細計劃,請參閱相關問題。React為DOM中所謂的輸入事件使用了不同的事件名稱,這令人困惑。雖然我們通常會避免在沒有明顯好處的情況下進行大的更改,但在這種情況下,我們還希望更改行為,以消除一些只在邊界情況下才需要的複雜性,比如突變受控輸入。因此,將這兩個更改一起執行是有意義的,並將其作為一個機會,使onInput和onChange能夠準確地工作於非受控組件的DOM事件。
  4. 大大簡化事件系統(#4751)。目前的活動系統自2013年首次實施以來幾乎沒有改變。它在React DOM和React Native之間被重用,因此它是不必要的抽象。它提供的許多填充對於現代瀏覽器來說是不必要的,而且其中一些會產生比解決的問題更多的問題。它還佔React DOM bundle大小的很大一部分。我們在這裡沒有一個非常具體的計劃,但是我們可能會完全劃分事件系統,然後看看如果我們更接近DOM給我們的東西,我們能做的最少。我們可以完全擺脫合成事件。我們應該停止產生事件冒泡,比如媒體事件,它們不會在DOM中產生泡沫,也沒有很好的理由產生泡沫。我們希望保留一些特定於響應的功能,比如在門戶中冒泡,但是我們將嘗試通過更簡單的方法(例如重新調度事件)來實現這一點。被動事件可能是其中的一部分。
  5. className→class(# 4331,也可以參見下面# 13525(評論))。這已經被提出無數次了。我們已經允許將class傳遞到React 16中的DOM節點。這樣做所造成的混亂不值得它試圖避免的語法限制。我們不會單獨做這個改變,但是結合上面的一切都是有意義的。請注意,我們不能在不發出警告的情況下允許這兩種情況發生,因為這使得組件生態系統很難處理。每個組件都需要學習正確地處理這兩個組件,並且它們之間存在衝突的風險。因為許多組件處理className(例如通過附加到它),所以它很容易出錯。

權衡

如果我們的目標是繼續為像React Native Web這樣的項目公開當前私有的React事件系統api,我們就不能做這些改變。然而,React Native Web需要一個不同的策略,因為React Fabric可能會將更多的responder系統轉移到原生端。

我們可能需要放棄與一些較老的瀏覽器的兼容性,並且/或者需要更多獨立的polyfill。我們仍然支持IE11,但我們可能不會試圖消除一些現有瀏覽器的差異——這是許多現代UI庫所採取的立場。

推廣計劃

在這個階段,這個項目非常具有探索性。我們不確定以上這些事情是否會成功。因為這些變化是顯著的,我們需要在Facebook上搜索它們,並以漸進的方式嘗試它們。這意味著我們將引入一個特性標誌,派生一些代碼,並在Facebook上為一小部分人啟用它。開源16.x版本將保留舊的行為,但是在master上,您將能夠在打開特性標誌的情況下運行它。

github.com/facebook/rea

推薦閱讀:

哪個沒心沒肺的人,沒有一段為某人掏心掏肺的曾經 | 酷聽科技
你可以用 Linux 中的 IP 工具做 3 件有用的事情
手把手,帶你認識Swift的幾個列印輸出語句
如何看待鎚子科技Revolution One 的愚人節廣告?
如何在開發過程中『優雅』的改需求

TAG:React | 科技 |