自分が開発しているプロジェクトで、React17.0.2でNext.jsを使用していたのですが、React18の正式リリースから2ヶ月、そろそろ頃合いかと思いReactを18.1.0にアップグレードしてみました。(併せてNext.jsも最新バージョンにアップグレード)
が、それからというもの、ローカルで開発環境を立ち上げているときだけ、何故かuseEffectが2回実行されるようになってしまいました。
こんなソースを書いてみました。普通なら、componentDidMount
と1回出力されるだけです。

(゜д゜)
ソースとにらめっこしても何もおかしな所はない、だけど何故かアンマウントを挟んで2回実行される。
不可解な現象に唸っていたところ、その理由と対処法が分かりましたので書いていきます。
StrictMode
結論から言うと、React18の新機能である「StrictMode」というのが原因です。直訳すると「厳密モード」ですかね。
現在、StrictMode は以下のことに役立ちます。
・安全でないライフサイクルの特定
・レガシーな文字列 ref API の使用に対する警告
・非推奨な findDOMNode の使用に対する警告
・意図しない副作用の検出
・レガシーなコンテクスト API の検出
・state の再利用性を保証する
という風に、ありがたい恩恵を授かれるそうです。(ソース) しかし…
今回実際の自分のケースでは、useEffectの中にSocket.IOのイベントハンドラーを記述していたのですが、このStrictModeの仕様が仇となり、イベントハンドラーが2つ待ち受けてる状態になってしまい、処理が二重に行われるといったことがありました。
※StrictModeについて、詳しくはこのページが非常にわかりやすいです。
ReactでStrictModeを無効化させる
無効化はとても簡単です。
プロジェクトルートにあるindex.js
を開き、renderメソッドの中にあるReact.StrictMode
タグを消します。
Next.jsでStrictModeを無効化させる
こちらも簡単で、プロジェクトのルートディレクトリーにあるnext.config.js
を開き、
3行目のreactStrictModeプロパティーをtrue
からfalse
にします。
編集できたら開発環境のサーバーを再起動します。

これで無事、開発環境においても意図した挙動をするようになりました👍
この記事は 2025/07/06 01:43:57 にビルドされました