快速重新整理 (Fast Refresh)
快速重新整理 (Fast Refresh) 是 Next.js 的一項功能,可在編輯 React 元件時提供即時反饋。在 9.4 或更新版本 的所有 Next.js 應用程式中,快速重新整理預設為啟用狀態。啟用 Next.js 快速重新整理後,大多數編輯內容應能在 一秒內 顯示,且不會遺失元件狀態。
運作原理
- 如果您編輯的檔案 僅匯出 React 元件,快速重新整理將僅更新該檔案的程式碼,並重新渲染您的元件。您可以編輯該檔案中的任何內容,包括樣式、渲染邏輯、事件處理程式或效果 (effects)。
- 如果您編輯的檔案包含 非 React 元件的匯出,快速重新整理將重新執行該檔案以及導入它的其他檔案。例如,若
Button.js
和Modal.js
都導入theme.js
,則編輯theme.js
將同時更新這兩個元件。 - 最後,如果您編輯的檔案被 React 樹之外的檔案導入,快速重新整理 將退回執行完整重新載入。您可能有一個檔案既渲染 React 元件,又匯出被 非 React 元件 導入的值。例如,您的元件可能還匯出一個常數,而一個非 React 工具檔案導入它。在這種情況下,考慮將該常數遷移到單獨的檔案中,並讓兩個檔案都導入它。這將重新啟用快速重新整理功能。其他情況通常也可以用類似方式解決。
錯誤恢復能力
語法錯誤
如果您在開發過程中出現語法錯誤,可以修正後再次儲存檔案。錯誤會自動消失,因此您無需重新載入應用程式。您不會遺失元件狀態。
執行時錯誤
如果您的錯誤導致元件內部出現執行時錯誤,您將看到一個情境化的錯誤覆蓋層。修正錯誤後,覆蓋層會自動消失,無需重新載入應用程式。
若錯誤未發生在渲染期間,元件狀態將被保留。若錯誤發生在渲染期間,React 將使用更新後的程式碼重新掛載您的應用程式。
如果您的應用程式中設有 錯誤邊界 (error boundaries)(這對於生產環境中的優雅降級是個好主意),它們會在渲染錯誤後的下一次編輯時重試渲染。這意味著擁有錯誤邊界可以防止您總是重置到根應用狀態。但請注意,錯誤邊界不應 過於 細粒度。它們在生產環境中被 React 使用,應始終有意識地設計。
限制
快速重新整理會嘗試保留您正在編輯的元件中的本地 React 狀態,但僅在安全的情況下進行。以下是您可能會看到每次編輯檔案時本地狀態被重置的幾個原因:
- 類別元件 (class components) 的本地狀態不會被保留(僅函式元件和 Hooks 會保留狀態)。
- 您正在編輯的檔案可能 除了 React 元件外還有其他匯出。
- 有時,檔案會匯出高階元件 (higher-order component) 的呼叫結果,例如
HOC(WrappedComponent)
。如果返回的元件是類別,其狀態將被重置。 - 匿名箭頭函式如
export default () => <div />;
會導致快速重新整理無法保留本地元件狀態。對於大型程式碼庫,您可以使用我們的name-default-component
codemod。
隨著更多程式碼庫轉向使用函式元件和 Hooks,您可以預期在更多情況下狀態會被保留。
提示
- 快速重新整理預設會保留函式元件(和 Hooks)中的 React 本地狀態。
- 有時您可能希望 強制 重置狀態並重新掛載元件。例如,這在調整僅在掛載時發生的動畫時非常有用。為此,您可以在編輯的檔案中任意位置添加
// @refresh reset
。此指令僅作用於該檔案,並指示快速重新整理在每次編輯時重新掛載該檔案中定義的元件。 - 您可以在開發過程中編輯的元件中加入
console.log
或debugger;
。 - 請記住導入是區分大小寫的。當您的導入與實際檔案名稱不符時,快速重新整理和完整重新載入都可能失敗。例如
'./header'
與'./Header'
。
快速重新整理與 Hooks
在可能的情況下,快速重新整理會嘗試保留元件在編輯之間的狀態。特別是,只要不更改其參數或 Hook 呼叫的順序,useState
和 useRef
會保留其先前的值。
具有依賴項的 Hook(如 useEffect
、useMemo
和 useCallback
)在快速重新整理期間會 始終 更新。在快速重新整理發生時,它們的依賴項列表將被忽略。
例如,當您將 useMemo(() => x * 2, [x])
編輯為 useMemo(() => x * 10, [x])
時,即使 x
(依賴項)未更改,它也會重新執行。如果 React 不這樣做,您的編輯將不會反映在畫面上!
有時,這可能導致意外的結果。例如,即使 useEffect
的依賴項陣列為空,它在快速重新整理期間仍會重新執行一次。
然而,撰寫能夠應對 useEffect
偶發重新執行的程式碼是個好習慣,即使沒有快速重新整理也是如此。這將使您更容易在後期為其引入新的依賴項,並且這也是 React 嚴格模式 (React Strict Mode) 所強制要求的,我們強烈建議啟用它。