當前位置: 妍妍網 > 碼農

停更600天,React 團隊到底在忙啥?

2024-02-16碼農

距離 React 上次版本更新(v18.2)已經過去了600 多天。在這段時間裏, ,其中不乏對 React 的期待、疑問和抱怨。那麽,React 團隊究竟在幕後忙些什麽呢?本文將深入探討 React 團隊最近的研究進展,以期為大家揭示他們正在努力的方向。

React 編譯器

React 編譯器已經不再是單純的研究計畫,而是已經在 Instagram.com 的生產環境中得到了實際套用。React 團隊正在努力將編譯器推廣至 Meta 的更多平台,並正在為首次開源釋出做準備。

我們知道,React 在狀態變化時有時會多次重新渲染。自 React 誕生之初,React 團隊針對此類問題的解決方案一直是手動記憶化。在當前的 React API 中,這通常意味著使用 useMemo useCallback memo API 來手動控制 React 在狀態變化時的重新渲染頻率。然而,手動記憶化並非理想的解決方案。它會使程式碼變得復雜和混亂,容易出錯,並且需要投入額外的工作來保持其最新狀態。

盡管手動記憶化是一個實用的折衷方案,但 React 團隊對此並不滿足。他們的願景是,當狀態發生變化時,React 能夠自動、精確地重新渲染 UI 的相關部份,而無需犧牲 React 的核心設計原則。React 團隊認為,React 的核心思想:將 UI 視為狀態的函式,並利用標準的 JavaScript 值和習慣用法,這是 React 對如此多開發者具有吸重力的關鍵。為此, React 團隊投入了大量精力來研發一個 React 的最佳化編譯器。

考慮到 JavaScript 語言的動態性和規則靈活性,對其進行最佳化往往極具挑戰性。然而,React 編譯器透過模擬 JavaScript 的規則和「React 的規則」來安全地編譯程式碼。例如,React 元件需遵循冪等性原則:在相同輸入下應返回相同值,並且不得修改 props state 值。這些規則不僅限制了開發者的操作範圍,還為編譯器最佳化提供了安全的空間。

當然,開發者有時會稍微違反一些規則,React 團隊的目標是讓 React 編譯器能夠盡可能多地在程式碼上直接執行。編譯器會智慧地檢測程式碼是否嚴格遵循 React 的規則,如果確認安全,就會編譯程式碼;若存在潛在風險,則會跳過編譯。為了驗證這一策略的有效性,目前正在使用 Meta 公司龐大且多樣化的程式碼庫進行測試。

對於希望確保程式碼遵循 React 規則的開發者,強烈推薦啟用嚴格模式並配置 React 的 ESLint 外掛程式。這些工具可以協助捕捉 React 程式碼中的潛在問題,提升套用品質,並為未來的功能(如 React 編譯器)做好鋪墊。React 團隊正在完善 React 規則的官方文件,並更新 ESLint 外掛程式,旨在幫助開發團隊更好地理解和套用這些規則,從而構建更穩健的套用。

操作(Action)

React 團隊正在探索透過「伺服端操作」將客戶端數據發送至伺服端的解決方案,以便執行資料庫變更和表單功能。在開發過程中,進一步擴充套件了這些 API,使其也支持僅在客戶端套用中的數據處理。

為了簡化這一綜合功能集,將其統稱為「操作」。透過「操作」,可以輕松地將函式傳遞給DOM元素,如 <form/> 標簽:

<form action={search}>
<input name="query"/>
<button type="submit">Search</button>
</form>

action 函式可以同步或異步執行。可以選擇在客戶端使用標準 JavaScript 定義它們,或在伺服端透過 'use server' 指令來實作。當使用操作時,React 將自動管理數據送出的生命周期,並提供如 useFormStatus useFormState 等 Hook,使能夠存取表單操作的當前狀態和響應。

預設情況下,操作在轉換過程中送出,確保在處理操作的同時,當前頁面仍然保持互動性。由於操作支持異步函式,因此還增加了在轉換過程中使用 async/await 的功能。這意味著,當發起異步請求(如 fetch )時,可以透過轉換的 isPending 狀態來展示待處理的UI,並在套用更新期間持續顯示該UI。

除了操作外,還推出了名為 useOptimistic 的新功能,用於 管理樂觀狀態更新 。此 Hook 允許套用臨時更新,這些更新將在最終狀態送出後自動回滾。 useOptimistic 利用了常規的 async/await 機制,因此無論是在客戶端使用 fetch ,還是在伺服端使用 Server Action,其工作方式都保持一致。

為了支持這一功能,庫作者可以利用 useTransition 在自己的元件中實作自訂的 action={fn} 內容。鼓勵庫開發者在設計元件 API 時采納操作模式,以確保為 React 開發者提供一致的使用體驗。例如,如果庫中包含一個 <Calendar onSelect={eventHandler}> 元件,建議也提供一個 <Calendar selectAction={action}> API。

雖然 React 團隊的初衷是專註於客戶端與伺服端之間的數據傳輸,透過伺服端操作(Server Actions)來實作,但最終理念是為所有平台和環境提供統一的編程模型。因此,如果在客戶端引入了新功能,會努力確保它也能在伺服器端執行,反之亦然。這種統一的API設計使套用無論執行在何處都能保持一致性,從而簡化了未來升級到不同環境的流程。

現在,操作(Actions)功能已在 Canary (預覽版)中釋出,並將隨 React 的下一個版本正式推出。

React Canary (預覽版)中的新功能

React Canary 的引入,提供了一種機制,允許在新功能的設計接近最終狀態時,便能夠采納並使用這些穩定的特性,而無需等待它們被正式釋出到穩定的版本中。

Canary 機制改變了開發 React 的方式。過去,新功能通常在 Meta 內部私下進行研究和構建,這意味著使用者通常只能在功能完全成熟並被釋出到穩定版本時才能體驗到。然而,現在有了 Canary,React 團隊選擇在公開環境中與社群合作,共同完善在 React Labs 部落格系列中分享的功能。這意味著,可以在功能仍在最終確定階段時,就及時了解到這些新功能,而不是等到它們完全釋出後。

目前, React Server Components 資源載入 文件後設資料 操作 等特性已經成功登陸 React Canary,並且已經在 react.dev 上為這些新特性提供了詳細的文件支持:

  • 指令: "use client" "use server" 是全棧 React 框架中打包工具的關鍵功能,它們定義了客戶端和伺服端之間的「界限」。 "use client" 提示打包工具生成 <script> 標簽(類似於 Astro Islands),而 "use server" 則指導打包工具建立 POST 端點(類似於 tRPC Mutations)。結合使用,它們讓你能夠構建可重用的元件,這些元件融合了客戶端互動性和相關的伺服端邏輯。

  • 文件後設資料: 現在為在元件樹中的任何位置渲染 <title> <meta> 和後設資料 <link> 標簽提供了內建支持。這種支持在所有環境中都是一致的,包括純粹的客戶端程式碼、伺服端渲染(SSR)和 React Server Components(RSC)。這繼承了由像React Helmet 這樣的庫開創的功能,並為其提供了官方的實作。

  • 資源載入: 整合了 Suspense 與各種資源的載入生命周期,如樣式表、字型和指令碼。這使得 React 能夠判斷 < style> <link> <script> 等元素中的內容是否已準備就緒,從而進行適當的渲染。此外,新增了資源載入 API,如 preload preinit ,為使用者提供了更精細的控制,以確定資源應在何時載入和初始化。

  • 操作: 如前所述,引入了操作(Actions)來管理從客戶端到伺服器的數據傳輸。可以將操作附加到 <form/> 等元素上,並使用 useFormStatus 來跟蹤其狀態, useFormState 來處理結果。最重要的是,透過 useOptimistic ,可以實作樂觀的UI更新,即在伺服端確認之前預先顯示預期的結果。

  • 由於這些功能相互依賴,單獨在穩定通道中釋出它們將極具挑戰性。沒有互補的 Hook 來存取表單狀態,釋出操作(Actions)將削弱其實際效用。同時,不整合伺服端操作(Server Actions)會導致在伺服端修改數據變得繁瑣。

    為了確保這些功能能夠協同工作,並為開發者在生產環境中提供完整的資源支持,必須在將它們釋出到穩定通道之前進行充分的驗證。React Canary 提供了逐個開發功能的便利,同時允許逐步釋出穩定的 API,直至整個功能集完善。

    目前,React Canary 中的功能集已經完備,並準備釋出。

    React 的下一個主要版本

    經過幾年的叠代,react@canary 現在已經準備好釋出到 react@latest。上面提到的新功能將完美相容任何套用環境,為生產使用提供了所需的一切。由於資源載入和文件後設資料可能對某些套用構成破壞性更改,因此 React 的下一個版本將是一個主要版本: React 19

    當然,釋出前的準備工作仍在進行中。React 19 不僅包含了眾多期待已久的功能增強,更引入了如 Web 元件支持等突破性的改進。目前,我們的重點在於完成這些功能的整合、做好釋出前的最後準備、完善新功能的文件,並向大家公布版本更新的詳細內容。

    在接下來的幾個月裏,React 團隊將分享更多關於 React 19 包含的內容、如何采用新的客戶端功能以及如何為 React Server Components 構建支持的資訊。

    離線功能(更名為「活躍」)

    ,React 團隊對一項正在研究的功能進行了重新命名,從原先的「離線」更名為「活躍」。原先的命名「離線」暗示此功能僅適用於套用中不可見的部份,但在深入研究過程中,我們意識到套用中的某些部份可能雖然可見,但並不活躍,例如模態視窗後面的內容。因此,新名稱「 活躍 」更能準確地反映此功能的核心——標記套用的某些部份為「活躍」或「不活躍」。

    目前,「 活躍 」功能仍在研究階段,下一步工作是完善為庫開發人員提供的基礎功能。考慮到當前的重點是釋出更完整的功能,暫時將這一領域的優先級降低。

    往期推薦