高速更新は、 React コンポーネントに加えられた変更の即フィードバックを提供する Next.js の機能です。高速更新は 9.4 もしくはそれ以上の全ての Next.js アプリケーションでデフォルト有効になっています。 Next.js の高速更新が有効になったことで、ほとんどの変更はコンポーネントの状態を失うことなく瞬時に表示されます。
Button.js
と Modal.js
が theme.js
をインポートしている場合、 theme.js
の変更は両方のコンポーネントを更新します。開発中にシンタックスエラーを作った場合、それを再度修正して保存できます。エラーは自動的に消え、アプリケーションをリロードする必要はありません。コンポーネントの状態を失いません。
コンポーネントの中でランタイムエラーに繋がるミスを作った場合、コンテキストオーバーレイが表示されます。エラーを修正することで、アプリケーションをリロードすることなく、自動的にオーバーレイは閉じられます。
レンダリングの際にエラーが発生しなかった場合、コンポーネントの状態は保持されます。レンダリングの際にエラーが発生した場合、 React は変更されたコードを使用してアプリケーションを再マウントします。
アプリに error boundary がある場合(これは本番環境で安全に失敗するのに適しています)、それらはレンダリングエラーの後、次の変更で再レンダリングします。つまり、error boundary があることによって、常にルートアプリの状態がリセットされることを防ぐことができます。しかし、error boundary は細かくしすぎないように注意してください。これらは React によって本番環境で使用され、常に意図的に設計されるべきです。
高速更新は変更しているコンポーネントのローカル React 状態を保持しようとしますが、それが安全である場合に限ります。ファイルの各変更でローカル状態がリセットされる理由は次のとおりです:
HOC(WrappedComponent)
などの高階コンポーネントを呼び出した結果をエクスポートします。返されたコンポーネントがクラスの場合、その状態はリセットされます。export default () => <div />;
のような匿名アロー関数は、高速更新でローカルコンポーネントの状態が保持されないようにします。大規模なコードベースの場合は、 name-default-component
codemod を使用できます。より多くのコードベースが関数コンポーネントと Hooks に移動するにつれて、より多くの場合に状態が保持されることを期待できます。
// @refresh reset
を追加します。このディレクティブはファイルに対してローカルであり、変更のたびにそのファイルで定義されているコンポーネントを再マウントするように高速更新に指示します。console.log
や debugger;
を置くことができます。可能であれば、高速更新は変更の間コンポーネントの状態を保持しようとします。特に、 useState
と useRef
は 引数や Hook 呼び出しの順番を変更しない限り、以前の値を保持します。
useEffect
、 useMemo
や useCallback
のような依存関係を持つ Hooks は高速更新の間、常に更新されます。高速更新が行われている間、依存関係のリストは無視されます。
例えば、 useMemo(() => x * 2, [x])
から useMemo(() => x * 10, [x])
へ変更しているとき、 x
(依存関係)が変更されていなくても再実行されます。もし React がそれをしなかった場合、変更は画面に反映されていません!
場合によって、これは予期せぬ結果を導きます。例えば、依存関係の空の配列を持つ useEffect
でも、高速更新の間 1 回再実行されます。
しかし、偶発的な useEffect
の再実行に対して耐性のあるコードを書くことは、高速更新がたとえ無くても良い習慣です。後で新しい依存関係を簡単に導入できるようになり、私達が有効にすることを強く推奨している React Strict Mode によって適用されます。