首頁 >web前端 >js教程 >React 更新筆記伴侶

React 更新筆記伴侶

Linda Hamilton
Linda Hamilton原創
2025-01-12 16:39:44891瀏覽

React Update Notes Companion

React 新主要版本的更新說明總是資訊密集得令人難以置信,而且框架本身非常廣泛,我總是發現自己在做筆記並與參考文件進行比較,以嘗試不僅僅是弄清楚發生了什麼變化以及如何使用它,以及更新說明中談到的各種主要概念實際上是如何在幕後工作的。 雖然React 的文檔非常齊全,但更新說明並不總是「足以」理解這些概念- 例如,在React 19 更新說明中,我發現useOptimistic 的範例令人困惑,而且實際上對於鉤子的實際工作原理有點不準確。

我決定把我在回顧 React 19 變化時所做的筆記寫下來,作為那些一直害怕梳理筆記並弄清楚它們的含義的人的伴侶 - 所以讓我們開始吧。

操作與表單處理/useActionState

第一個重大改進是表單處理的巨大改進。 React 已逐漸致力於消除樣板檔案並更好地與原生 HTML 表單集成,其新的 useActionState 就是這項推動的一部分。它旨在幫助改進錯誤處理(因為它現在是內建的),它會自動追蹤載入狀態,以便您不必不斷在掛起狀態下手動編碼,並改進了對漸進增強的支援。

現在,我發現為useActionState 提供的程式碼範例非常混亂,事實上這個程式碼範例是我開始寫這篇文章的全部原因- 事實上,useActionState 有兩個部分,它們組合在例如為了節省空間,但最終大大降低了清晰度。 useActionState 傳回一個元組,用於追蹤表單提交中的非同步操作何時完成,而您傳遞的操作的修改版本將直接傳遞到表單。 useActionState 本身需要兩個輸入 - 非同步 formAction(呼叫時接收先前狀態和表單資料作為參數)和初始狀態 - 可以為 null、零或變數。

如果您的表單尚未提交,則先前的狀態是initialState。如果表單之前已經提交過,那麼它就是提交的任何內容 - 在伺服器功能中,您實際上可以在水合發生之前顯示伺服器回應。 useActionState 最後可以接受帶有表單要修改的唯一頁面 URL 的字串。 換句話說,它還可以接受可選的永久連結參數,這對於漸進式增強特別有用 - 如果用戶在 JavaScript 加載之前提交表單,它會告訴瀏覽器導航到哪裡。

最後,useActionState傳回的元組是一個數組,其中包含當前狀態(在初始渲染期間它是您的initialState值),您可以將react修改的formAction作為action傳遞給表單或將按鈕作為prop傳遞給,和一個isPending 標誌/狀態變數。我很期待看到 React 團隊還會推出哪些其他新開發成果,因為這個似乎特別有用。

React-DOM 更新

行動

任何使用過 NextJS 和表單操作的人都會熟悉這個 React-dom 添加,而且 Reac 團隊似乎已經決定表單操作已經準備好迎接黃金時段了。對於沒有在 NextJS 或 React 之上的其他框架中使用過它們的人來說,它們基本上是一種透過使用本機表單提交來增強 React 效能的方法。 您可以透過 action 屬性傳遞本機表單提交,而不是 onClick - 傳遞給 action 或 formAction 的任何函數都會自動處理其提交。 React 也會自動重置任何不受控制的表單欄位。您也可以透過 API 手動選擇重置它。 React 團隊也將錯誤處理與錯誤邊界整合在一起。 我不會談論太多,因為我假設大多數人都記得 NextJS 中的它們,但如果有人有疑問,我可以寫一篇後續文章。

useFormStatus 鉤子

這是一個很好的補充,可以幫助您了解表單中發生的情況,而無需使用道具鑽探或使用上下文 - 如果您問為什麼不使用道具鑽探,它與保持程式碼可維護且易於修改有關。 至於上下文,過度使用上下文將導致效能問題,因為每當上下文中的某些內容發生變化時,訂閱特定上下文的每個元件都會重新呈現。 因此,它可以整理程式碼,減少出錯的機會,並防止您影響應用程式的效能。

該鉤子傳回一個具有四個屬性的物件:pending - 一個布林值,表示是否有待處理的提交,data - 一個包含父表單提交的資料的formData 物件(如果沒有活動提交或父表單,則為null )、方法(get 或post)和操作- 這是透過action 屬性傳遞的操作。

使用樂觀鉤子

管理樂觀更新的更簡單的新方法。 如果您不熟悉樂觀更新,這表示在伺服器端更新發生之前更新用戶端顯示。 如果您曾經喜歡過某件事,請看過動畫播放並將其在螢幕上註冊為喜歡,然後收到一條提示「喜歡失敗」的 toast 錯誤,這是由於樂觀渲染造成的。

useOptimistic 鉤子接受一個你想要樂觀渲染的有狀態變數和一個更新函數,它必須是一個純函數 - 換句話說,一個沒有副作用的確定性函數。基本上,更新函數會擷取狀態更新的來源 - 通常類似於 formData.get(‘name’)。 useOptimistic 然後傳回兩個值:樂觀狀態和 addOptimistic 函數。

我發現這方面的文件有點薄弱,特別是在使用流程方面 - 基本上,您調用 useOptimistic 並將其傳遞給您想要顯示樂觀更新的初始狀態和更新函數。您將收到兩個函數 - 新的樂觀增強狀態值 (optimisticState) 和一個樂觀地更改狀態的函數。當使用者提交新值時,您可以呼叫第二個函數(在文件中稱為 addOptimistic),並將使用者提交的值傳遞給它。在您的元件中,每當您想要樂觀地呈現有狀態變數時,您都可以將樂觀增強的有狀態值傳遞給它。

總的來說,我真的很喜歡這種更標準化的執行樂觀更新的方式- 我之前在NextJS 中緩存和進行樂觀更新時遇到過問題,所以創建樂觀更新的標準化方法很棒,我相信這會冒泡到NextJS(如果還沒有)。

使用API​​

這是一個超級密集的 API,它是一種在 React 渲染頁面時訪問資源的全新方式 - 使用的確切措辭是「在渲染中讀取資源」。那麼它具體是做什麼用的呢? 這個新的 API 可用於存取條件或循環內部的元件資訊。 如果您不熟悉為什麼它有用,它與 React 的渲染過程的工作原理有關。 React/React-Fiber 依賴於每次都以相同的順序渲染所有內容,這就是為什麼在渲染過程中通常無法存取大多數鉤子的原因。 更清楚地說,狀態實際上是根據呼叫鉤子的順序來追蹤的,因此如果以不可預測的順序呼叫鉤子,最終會出現渲染錯誤。一個很好的例子是根據使用者是否登入來存取主題上下文。

那為什麼這是一個重要的發展呢? 這意味著您只能在實際需要時載入資訊/數據,例如僅當使用者實際登入時,您才會載入特殊主題的 css。資料必須是可序列化的,因此這意味著您可以將承諾從伺服器元件發送到客戶端元件,而實際上它已經在運行中 - 這意味著瀑布請求更少,並且它們會自動並行放置。 值得注意的是,在伺服器元件中工作時,您實際上應該更喜歡使用async/await 而不是用於資料擷取- 這是因為async/await 將從其停止的位置恢復渲染,而使用將觸發完全重新渲染資料解析後的元件。當然,我還想指出,這個變化實際上也意味著,如果你配置使用不正確,你就有了一個新的潛在的瀑布請求來源。

需要注意的一件非常重要的事情是,您不能在 try/catch 區塊中使用「use」API - 這是因為「use」在使用 Promise 呼叫時會自動使用 React Suspense 邊界。 try/catch 區塊會阻止您達到 React 級別,因為任何錯誤實際上都會在您達到 React 之前停止 JS 級別的執行,從而破壞功能。 與其他鉤子一樣,它們必須位於特定元件或函數範圍的頂層(同樣,由於渲染順序)。

所以,「使用」的真正目的是幫助您存取上下文以有條件地渲染事物,並且僅在實際需要時才獲取資料。這是讓 React 不再那麼晦澀難懂、簡化條件資料擷取、改善開發體驗並一次性提高效能的又一步。它需要更有經驗的 React 開發人員重新學習如何做主題之類的事情,但我認為這使得新用戶更容易使用該框架,這總是很棒的。

新的 React Dom 靜態 API

這兩個新的靜態 API prerender 和 prerenderToNodeStream 都是對 renderToString 的改進,renderToString 用於伺服器端渲染 (SSR)。這些新的改進是為了使用 renderToString 進行靜態網站產生 (SSG)。 與可以在內容區塊可用時發送內容區塊的傳統串流 SSR 不同,這些新 API 專門等待所有資料加載,然後再產生最終 HTML。它們旨在與 Node.js Streams 和 Web Streams 等現代串流環境無縫協作,但它們故意不支援串流部分內容 - 相反,它們確保您在建置時獲得完整、完全載入的頁面。它們與傳統的串流 SSR 方法不同,傳統的串流 SSR 方法會在資料可用時傳送預先渲染網站。

我們已經在 React 之上建立了支援 SSG 的框架,例如 NextJS,但這旨在成為 React 針對 SSG 的本機功能。擁有 SSG 的框架使用 renderToString,然後圍繞它建立自己的複雜資料來獲取協調。 這對於用戶自己創建來說非常困難,並且這些框架使用極其複雜的管道來做到這一點。 這些新方法本質上是允許在靜態HTML 生成期間加載數據,如果您不熟悉SSG,它本質上是在構建時渲染所有內容,並且無疑是渲染頁面的最快方法,因為它沒有根據用戶請求呈現頁面,因此對於不想使用Next 之類的功能的人來說,擁有這種功能非常棒,因為Next 要么需要在Vercel 上部署,要么需要極其複雜的部署過程。

伺服器元件

React 伺服器元件的概念對於使用過 NextJS 最新版本的人來說並不陌生,但對於沒有使用過的人來說,伺服器元件是一種圍繞資料獲取的新範例。坦白說,伺服器元件(和伺服器操作)的概念本身就值得寫一整篇文章,但簡單地總結一下這個概念,伺服器元件始終在發送到客戶端之前在伺服器上呈現,即使在載入javascript 之後也是如此。 這意味著後續渲染是在伺服器端完成的。

這些元件的主要優點是安全性和數據獲取:如果您在伺服器元件內請求數據,請求資訊永遠不會顯示在客戶端,只會顯示回應,從而更加安全。 API、端點等根本無法在客戶端存取。它還減少了套件的大小,因為所述操作的 JavaScript 永遠不會發送到客戶端。它還允許您在伺服器上執行記憶體或計算密集型操作,以減輕功能較弱的電腦上的渲染負擔。 它們還減少了客戶端瀑布,因為可以在靠近資料庫的電腦上執行順序資料獲取,但當然它也開啟了全新伺服器端瀑布的可能性,因為您的開發人員無法存取來自測試瀏覽器開發人員的簡單請求資訊工具,並且必須使用OpenTelemetry 收集器和檢視器之類的東西來檢查它們。最後,伺服器元件也非常適合漸進增強。

伺服器元件也有一系列限制:你不能使用本地瀏覽器API(本地儲存、視窗等),React hooks 的工作方式會有所不同,你不能依賴或使用狀態,而且你可以'不使用事件處理程序,因此組件的使用者互動性明顯很小。 基本上,將此範例視為伺服器元件中的資料擷取和客戶端元件上的互動。

對於任何剛接觸伺服器元件的人來說,最重要的警告是您不能將它們導入客戶端元件- 如果您這樣做,這將出錯(假設您已經添加了一些資料獲取),因為它會導致編譯器處理所述伺服器元件作為客戶端元件。如果要將伺服器元件傳遞給客戶端元件,則需要透過 {children} 屬性傳遞它。

伺服器操作

這是另一個複雜的主題,對您如何建立產品和功能有很多影響,這些也已經在 NextJS 中出現了一年左右。 伺服器操作是透過在檔案頂部鍵入「use server」來聲明的,並傳遞對所述伺服器函數的直接引用,然後可以從客戶端元件內部呼叫函數。

在某種程度上,它們在概念上類似於遠端過程呼叫(RPC) - 它們都允許您從客戶端呼叫伺服器端函數,都抽象化了客戶端-伺服器互動的複雜性,並且都處理序列化和反序列化,但是有一些關鍵差異需要注意。 伺服器操作的主要好處是它們可以與React 的漸進增強配合使用,幫助跨客戶端/伺服器邊界強制執行類型安全,具有內建的效能最佳化(與漸進增強相關),並且與React 生態系統有更無縫的整合因為它們提供內建的待處理狀態,並自動與本機表單提交整合。

當您談論現代RPC(例如gRPC)時,它已經具有類型安全性和一些性能優化,伺服器操作的主要優勢通常可以歸結為內建表單處理和漸進增強,但重要的是它也有效具有反應懸念和錯誤邊界。最重要的是,部署要簡單得多,因為您不一定需要為gRPC 設定單獨的伺服器,因此這些對於較小的專案來說絕對更理想,儘管當涉及到較大的專案時,我可以看到gRPC 更可取,因為它在後端語言等方面為您提供了更大的靈活性

作為提供者的上下文

這本質上是語法的簡化,幫助 React 擁有更清晰的聲明性語法。 說實話,除了「我喜歡」之外,我沒什麼好說的。

Ref 作為 Prop 和 Ref 的清理函數

以前,要清理引用,您必須在組件內部執行空檢查,並且引用將在某種程度上不確定的時間被清理。當元件卸載時,React 會使用 null 呼叫您的 ref 回調,要求您明確處理附加和分離情況。新 ref 語法的優點是確定性清理 - 這意味著現在使用外部資源和第三方程式庫會更加容易,因為您將確切地知道何時發生 ref 清理(卸載時)。 使用新方法,您可以直接返回清理函數。 TypeScript 整合需要明確傳回語句,以避免清理函數出現歧義。

我真的很喜歡這種實作方式,因為它與 useEffect 的模式相同 - 保持整個框架的一致性非常棒。我認為這個新的引用清理對於 WebGL 上下文和其他大量資源非常有用,而且對於處理使用本機 JS 方法新增的 DOM 事件偵聽器也非常有用。 這是因為以前,react 會在清理時刪除對 dom 元素的引用…但是如果你這樣做了,刪除事件監聽器就會變得更加複雜,因為你已經丟失了對它們所附加的組件的引用。 因此,您必須將引用儲存在元素之外,從而增加了一層複雜性。現在,您可以刪除元件傳回函數內的事件偵聽器,因為您保留對所述傳回函數內的 ref 的存取權。這也意味著我們在大多數情況下不再需要擔心 null 情況,因為在使用清理函數時,React 不會再使用 null 來呼叫 ref。清理函數本身取代了該功能,使我們的程式碼更乾淨、更可預測。

useDeferredValue

useDeferredValue 掛鉤的目的在於管理計算量大的操作,同時維護響應式使用者介面。它透過允許元件在後台計算或獲取新資料時顯示先前的“陳舊”值來實現此目的。一個常見的用例是搜尋功能,它會在用戶鍵入時顯示結果 - 如果沒有延遲,每次按鍵都可能觸發昂貴的搜尋操作,從而使輸入感覺緩慢。使用 useDeferredValue,介面可以透過顯示先前的搜尋結果同時計算新的搜尋結果來保持回應。

這個新添加是對該鉤子初始加載行為的重要改進。以前,第一次渲染將立即使用傳遞給 useDeferredValue 的任何值,這可能會在開始時觸發昂貴的計算。新版本可讓您提供立即顯示的輕量級初始值(例如空字串),同時在背景處理更昂貴的值。這意味著您可以向使用者顯示安全預設值的即時回饋,然後在昂貴的計算完成後使用真實資料更新它。從本質上講,這使得 useDeferredValue 能夠更好地提高效能。

文檔元資料新增

這些新的變更是為了在實際組件內添加各種元資料標籤。他們會討論三個選項:

和 <meta>。 值得注意的是,<title>沒有重複資料刪除 - 每個儲存庫您只打算使用它一次。另外兩個,<link>和<meta>,在重複資料刪除方面有一些相當複雜的交互,在學習之後,我認為這些交互對於 90% 的用戶來說並不是特別相關。 <p>這些變更的主要好處是它們允許元件真正獨立:它們現在可以管理自己的元資料以及樣式和腳本。您不再需要弄清楚如何將元資料提升到頂層或使用庫來完成此操作,這使得 SEO 變得更容易。 SPA 中的不同頁面可以更輕鬆地擁有不同的元數據,而不會冒元數據與頁面上顯示的內容不同步的風險,而這以前是不同頁面擁有不同元數據時存在的風險。 </p> <p><strong>樣式表支援</strong></p> <p>人們可能已經使用 tailwind 太久了,以至於他們已經忘記了,但是運行非封裝的 CSS 可能會因為樣式表的載入方式(即載入順序優先規則)而產生問題。首先,您最終可能會看到閃爍的無樣式內容- 任何時候在CSS 下載完成之前加載和呈現HTML 時,它都會顯示為完全白色的頁面,通常在具有大量字體大小和本機圖像大小的單列中,這通常使其無法讀取。 </p> <p>此外,CSS 載入順序規則可能會產生其他問題:例如,如果您有具有相同特異性的規則,但希望它們按特定順序載入。例如,當您有不同的主題選項(例如深色模式)時,這是相關的。如果深色模式 CSS 打算最後加載,但深色模式的 CSS 檔案首先加載,則最終可能會出現深色模式為淺色,或者應用程式的某些部分遵守規則而其他部分不遵守規則的情況。 t 堅持。 </p> <p>有許多解決方案可以避免這種情況,例如 JS 中的 CSS,將所有 CSS 載入到 </p> 中。然而,這些新的 CSS 變更旨在透過以聲明方式設定優先順序來幫助管理這些問題 - 它還確保放置在元件中的任何樣式表在元件本身呈現之前載入。 它還內建了重複資料刪除功能,因此當您重複使用包含樣式表連結的元件時,您不會最終多次載入相同的樣式表。 <p>存取這個新功能的方式(在渲染元件之前等待 css 載入、自動將 CSS 提升到頭部等)也非常簡單 - 您只需要在特定的 <link> 中包含優先順序;成分。 總的來說,我是打字稿的愛好者,所以它並不能完全解決我的任何特定問題,但我確信這將是非常有用的大型遺留項目。 </p> <p><strong>非同步腳本支援</strong></p> <p>這解決了一個邊緣情況,而不是創建一個新的核心功能讓人們擔心 - 使用 <script> 手動添加/直接管理腳本根據我的經驗,標籤在現代 React 中非常罕見。 大多數開發人員都使用 webpack 或 vite 等捆綁器、套件管理器、導入語句,如果需要動態載入腳本,他們會使用 useEffect 之類的東西。 然而,這與 SSR 和更好的 UX 相關,以避免上述 <head> 中內容載入順序的問題。 </script></p> <p>由於腳本可以非同步加載,這意味著在沒有正確樣式的情況下加載 React 應用程式的可能性會大大降低。 這項變更也與管理需要直接腳本標籤的遺留系統的開發人員或負責管理無法捆綁的第三方腳本(例如分析、小部件等)或防止特別繁重的腳本(例如影片)的開發人員相關。播放器)在有必要提高性能之前加載,但由於我沒有這些經驗,所以我無法真正評論更多。 </p> <p><strong>支援預先載入資源</strong></p> <p>用於管理資源預先載入的新API 非常有趣,特別是對於必須確保網路條件千差萬別的全球受眾獲得無縫加載體驗的大型企業,以及依賴不同來源的大量第三方資源的內容密集型應用程序,對於任何感知性能對用戶保留很重要的應用程式(說實話,這幾乎就是一切)</p> <p>然而,大多數基於 React 的框架(例如 Next、Remix 等)往往已經管理了這一點 - 我不太確定這些新的 API 將如何與所述框架交互,但似乎是這樣。將成為新的衝突來源,也是使用這些框架並嘗試使用這些新 API 優化效能時需要牢記的重要事項。 </p> <p>雖然預先載入絕對是具有最廣泛用例(載入樣式表等)的 API,但由於上述問題,我認為最相關的是 preinit - 這是一種立即啟動的硬加載,旨在急切加載腳本。 我能想到的最明顯的用途是立即在購物車評論中加載條紋 - 這應該會顯著加快結帳過程,這是電子商務的一個步驟,您絕對不想因為性能問題而失去客戶。 </p> <p><strong>第三方腳本相容性</strong></p> <p>考慮到瀏覽器插件越來越常見,這是一個非常受歡迎的變化- 我能想到的一些修改DOM 結構的例子可能會從這一變化中受益,包括廣告攔截器、價格比較工具、語法/AI 助手插件和翻譯擴充。在沒有實際閱讀水合現在如何運作的情況下,對此沒有太多可說的,儘管主要的變化似乎是編譯器跳過了意外的標籤。 </p> <p><strong>更好的錯誤回報</strong></p> <p>我發現這部分非常不言自明。 錯誤處理的變化總是受歡迎的——以前存在的錯誤垃圾郵件總是讓追蹤特定錯誤變得有點困難。如果您使用一些維護不太好的第三方解決方案,這些解決方案往往會引發大量錯誤,這一點尤其重要。 <br> 支援自訂元素</p> <p>這部分對我來說特別有趣,因為我以前從未聽說過自訂元素。 簡而言之,自訂元素是一種新的 Web 標準,可讓開發人員建立自己的 HTML 元素。 由於遵循上述Web 標準,它們旨在在任何頁面上運行並且與框架無關- 例如,您可以編寫一個在所有個人專案中常用的元件(您傾向於以svelte 的方式進行操作),然後將其用於較小的專案您為新創公司所做的合約工作或vue 中的短期合約等</p> <p>React 用於將無法識別的 props 視為屬性而不是實際屬性 - 新的更新添加了一個允許正確使用 props 來創建自訂元素的系統。看來透過此更改,現在完全支援在 React 中使用自訂元素。 順便說一句,除了props 問題之外,React 的合成事件系統過去也存在不相容性(現已解決)——自訂元素無法與系統完全集成,因此在某些情況下您實際上必須手動添加帶有ref 的事件偵聽器以及其他解決方法。 </p>

以上是React 更新筆記伴侶的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn