跳到內容
簡介架構Fast Refresh

Fast Refresh

Fast Refresh 是一個整合到 Next.js 中的 React 功能,讓您在儲存檔案變更時,能夠即時重新載入瀏覽器頁面,同時保持暫時性的客戶端狀態。在 9.4 或更新版本的所有 Next.js 應用程式中,預設為啟用。啟用 Fast Refresh 後,大多數編輯應該在一秒內可見。

運作方式

  • 如果您編輯的檔案僅匯出 React 組件,Fast Refresh 將僅更新該檔案的程式碼,並重新渲染您的組件。您可以編輯該檔案中的任何內容,包括樣式、渲染邏輯、事件處理程序或效果。
  • 如果您編輯的檔案匯出不是 React 組件的內容,Fast Refresh 將重新執行該檔案以及匯入它的其他檔案。因此,如果 Button.jsModal.js 都匯入 theme.js,則編輯 theme.js 將更新這兩個組件。
  • 最後,如果您編輯的檔案React 樹狀結構之外的檔案匯入,Fast Refresh 將會回退到執行完整重新載入。您可能有一個檔案,它渲染一個 React 組件,但也匯出一個值,這個值被一個非 React 組件匯入。例如,您的組件也可能匯出一個常數,而一個非 React 實用程式檔案匯入它。在這種情況下,請考慮將常數遷移到一個單獨的檔案,並將其匯入到這兩個檔案中。這將重新啟用 Fast Refresh 的運作。其他情況通常可以用類似的方式解決。

錯誤復原能力

語法錯誤

如果您在開發期間犯了語法錯誤,您可以修正它並再次儲存檔案。錯誤將自動消失,因此您無需重新載入應用程式。您不會遺失組件狀態

運行時錯誤

如果您犯了一個錯誤,導致組件內部發生運行時錯誤,您將會看到一個情境化的覆蓋層。修正錯誤將自動關閉覆蓋層,而無需重新載入應用程式。

如果錯誤不是在渲染期間發生,組件狀態將會被保留。如果錯誤確實在渲染期間發生,React 將使用更新後的程式碼重新掛載您的應用程式。

如果您的應用程式中有錯誤邊界 (這對於生產環境中的優雅降級來說是個好主意),它們將在渲染錯誤發生後的下一次編輯時重試渲染。這表示擁有錯誤邊界可以防止您始終被重置為根應用程式狀態。但是,請記住,錯誤邊界不應該細微。它們在生產環境中被 React 使用,並且應該始終經過有意的設計。

限制

Fast Refresh 嘗試在您正在編輯的組件中保留本機 React 狀態,但前提是這樣做是安全的。以下是一些原因,說明為什麼您可能會看到每次編輯檔案時本機狀態都會被重置

  • 本機狀態不會為類別組件保留 (只有函式組件和 Hooks 會保留狀態)。
  • 您正在編輯的檔案除了 React 組件外,可能還有其他匯出。
  • 有時,一個檔案會匯出呼叫高階組件 (例如 HOC(WrappedComponent)) 的結果。如果返回的組件是一個類別,則其狀態將被重置。
  • 匿名箭頭函式 (例如 export default () => <div />;) 會導致 Fast Refresh 無法保留本機組件狀態。對於大型程式碼庫,您可以使用我們的 name-default-component codemod

隨著您的更多程式碼庫轉移到函式組件和 Hooks,您可以期望在更多情況下保留狀態。

提示

  • Fast Refresh 預設會保留函式組件 (和 Hooks) 中的 React 本機狀態。
  • 有時您可能想要強制重置狀態,並重新掛載組件。例如,如果您正在調整僅在掛載時發生的動畫,這可能會很方便。為此,您可以在您正在編輯的檔案中的任何位置新增 // @refresh reset。此指令是檔案本地的,並指示 Fast Refresh 在每次編輯時重新掛載在該檔案中定義的組件。
  • 您可以將 console.logdebugger; 放入您在開發期間編輯的組件中。
  • 請記住,匯入是區分大小寫的。當您的匯入與實際檔案名稱不符時,快速和完整重新整理都可能失敗。例如,'./header''./Header'

Fast Refresh 與 Hooks

在可能的情況下,Fast Refresh 會嘗試在編輯之間保留組件的狀態。特別是,useStateuseRef 會保留它們之前的值,只要您不更改它們的參數或 Hook 呼叫的順序。

具有依賴項的 Hooks (例如 useEffectuseMemouseCallback) 在 Fast Refresh 期間總是會更新。在 Fast Refresh 發生時,它們的依賴項清單將被忽略。

例如,當您將 useMemo(() => x * 2, [x]) 編輯為 useMemo(() => x * 10, [x]) 時,即使 x (依賴項) 沒有更改,它也會重新執行。如果 React 不這樣做,您的編輯將不會反映在螢幕上!

有時,這可能會導致意外的結果。例如,即使是具有空依賴項陣列的 useEffect 仍然會在 Fast Refresh 期間重新執行一次。

但是,即使沒有 Fast Refresh,編寫能夠應對 useEffect 偶爾重新執行的程式碼也是一個好的做法。這將使您以後更容易向其引入新的依賴項,並且這是由 React Strict Mode 強制執行的,我們強烈建議啟用它。