Fast Refresh
Fast Refresh 是一個整合到 Next.js 中的 React 功能,讓您在儲存檔案變更時,能夠即時重新載入瀏覽器頁面,同時保持暫時性的客戶端狀態。在 9.4 或更新版本的所有 Next.js 應用程式中,預設為啟用。啟用 Fast Refresh 後,大多數編輯應該在一秒內可見。
運作方式
- 如果您編輯的檔案僅匯出 React 組件,Fast Refresh 將僅更新該檔案的程式碼,並重新渲染您的組件。您可以編輯該檔案中的任何內容,包括樣式、渲染邏輯、事件處理程序或效果。
- 如果您編輯的檔案匯出不是 React 組件的內容,Fast Refresh 將重新執行該檔案以及匯入它的其他檔案。因此,如果
Button.js
和Modal.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.log
或debugger;
放入您在開發期間編輯的組件中。 - 請記住,匯入是區分大小寫的。當您的匯入與實際檔案名稱不符時,快速和完整重新整理都可能失敗。例如,
'./header'
與'./Header'
。
Fast Refresh 與 Hooks
在可能的情況下,Fast Refresh 會嘗試在編輯之間保留組件的狀態。特別是,useState
和 useRef
會保留它們之前的值,只要您不更改它們的參數或 Hook 呼叫的順序。
具有依賴項的 Hooks (例如 useEffect
、useMemo
和 useCallback
) 在 Fast Refresh 期間總是會更新。在 Fast Refresh 發生時,它們的依賴項清單將被忽略。
例如,當您將 useMemo(() => x * 2, [x])
編輯為 useMemo(() => x * 10, [x])
時,即使 x
(依賴項) 沒有更改,它也會重新執行。如果 React 不這樣做,您的編輯將不會反映在螢幕上!
有時,這可能會導致意外的結果。例如,即使是具有空依賴項陣列的 useEffect
仍然會在 Fast Refresh 期間重新執行一次。
但是,即使沒有 Fast Refresh,編寫能夠應對 useEffect
偶爾重新執行的程式碼也是一個好的做法。這將使您以後更容易向其引入新的依賴項,並且這是由 React Strict Mode 強制執行的,我們強烈建議啟用它。
這有幫助嗎?