React Strict Modeの「二重実行」を恐れるな。それは君のコードを強くする「試練」だ
フロントエンドの現場で、こんな場面に遭遇したことはないだろうか。
`useEffect` 内でログを仕込んだら、開発環境のコンソールに同じログが2回流れてくる。「あれ?バグか?」「リクエストが2回飛んでるじゃないか!」と焦って、慌てて依存配列を調整したり、無理やり `useRef` でフラグを立てて実行を抑制したりする……。
はっきり言おう。それ、Reactからの「もっと綺麗に書け」という愛のムチだ。
今日は、なぜReactが開発環境でわざわざ副作用を二回実行するのか、そしてその裏にある「冪等性(べきとうせい)」というプロフェッショナルの必須概念について、現場の視点から解説する。
—
なぜ「二回」なのか?:リアクティブな世界への招待
React Strict Mode(`
Reactの世界において、コンポーネントは「UIを生成する関数」であり、副作用(API通信、購読、DOM操作)はそれに付随する「おまけ」だ。本来、副作用は「開始」と「終了(クリーンアップ)」が正しく対になっていれば、何度繰り返されても安全であるべきなんだ。
もし、2回実行されただけで挙動がおかしくなるようなコードであれば、それは「Reactのライフサイクルを正しく制御できていない」というシグナルだ。例えば、ユーザーが画面を行き来しただけで購読が重複したり、メモリリークを起こしたりするリスクを、開発環境のうちに炙り出しているわけだ。
—
現場で使える「冪等性」を守る実装パターン
では、どう書けば「2回実行されても安全なコード」になるのか。実務で最もよく使う「購読(Subscription)」のパターンで見てみよう。
import { useEffect, useState } from ‘react’;
const ChatRoom = ({ roomId }) => {
useEffect(() => {
// 1. 外部リソースへの接続を開始(セットアップ)
const connection = createConnection(roomId);
connection.connect();
console.log(`ルーム ${roomId} に接続しました`);
// 2. クリーンアップ関数を定義(ここが最重要!)
// Strict Modeで2回実行される際、1回目の接続をここで確実に切断する
return () => {
connection.disconnect();
console.log(`ルーム ${roomId} から切断しました`);
};
// 依存配列に roomId があるため、roomIdが変わるたびに
// 「切断→再接続」のフローが正しく実行される
}, [roomId]);
return
;
};
このコードが美しい理由
- クリーンアップの完備: `return` で返された関数が、次に `useEffect` が実行される直前や、コンポーネントがアンマウントされるタイミングで確実に呼ばれる。
- 冪等性の担保: どんなに接続と切断を繰り返しても、常に「現在の状態」と「外部の同期先」が1対1で一致する。これがReactが求める「宣言的」な副作用の姿だ。
—
よくある「悪い癖」と脱却のヒント
たまに、`useEffect` の中でフラグ変数を作って「2回目以降は実行しないようにする」といったハックを見かけるが、それは絶対におすすめしない。
// ❌ やってはいけないこと
useEffect(() => {
if (ref.current) return; // 実行をガードする
ref.current = true;
doSomething();
}, []);
これは「Reactのライフサイクルから逃げている」状態だ。これをしてしまうと、将来的に `roomId` が変更されたときや、コンポーネントが再利用される際に予期せぬバグを引き起こす。Reactが提供する「クリーンアップ関数」という仕組みを信じて、正攻法で書くのが一番の近道だ。
—
まとめ:Strict Modeはデバッグの強力な味方
Strict Modeでの二重実行は、あなたのコードの「クオリティチェック」だ。
1. クリーンアップ関数が書かれているか?
2. 副作用の開始と終了が対称的か?
3. 依存配列に漏れはないか?
これらを意識するだけで、あなたの書くコンポーネントは格段に堅牢になる。もし2回実行されて困る処理があるなら、それは「Reactの外側の世界(外部ストレージやグローバルなDOM)」と綺麗に同期できていないというサインだ。
恐れず、むしろ「自分のコードをテストしてくれてありがとう」という心持ちで、Strict Modeと向き合ってみてほしい。そうすれば、君もフロントエンドの真のアーキテクトに一歩近づけるはずだ。
現場からは以上だ。また何かあればいつでも聞いてくれ。

コメント