導入:なぜコンポーネントが2回レンダリングされるのか?
Reactで開発をしていると、コンソールログが2回出力されたり、useEffectの中身が意図せず2回実行されたりして「バグかな?」と焦った経験はありませんか?実はそれ、Reactが意図的に行っている「Strict Mode」によるチェック機能かもしれません。
Strict Modeは、開発者が将来的なバグを未然に防ぎ、より堅牢なアプリケーションを作るための「守護神」のような存在です。なぜReactがわざわざこのような挙動をするのか、その理由と活用方法を解説します。
基礎知識:Strict Modeとは何か?
Strict Mode(ストリクトモード)とは、Reactのローカル開発環境でのみ有効になる「デバッグ用ツール」です。これを有効にすると、コンポーネントのレンダリングや副作用(useEffectなど)が開発時に意図的に2回実行されます。
これにより、以下の問題を発見しやすくなります。
・副作用のクリーンアップ漏れ:画面を離れた後もタイマーや通信が動き続ける問題
・状態の直接変更(ミューテーション):Reactのルールを破った状態管理の検知
・非推奨なAPIの使用:将来のバージョンで廃止される古いコードの特定
実装:Strict Modeの確認方法
Reactプロジェクト(特にcreate-react-appやVite)では、デフォルトでsrc/main.jsxやindex.js内で以下のように囲まれています。
サンプルプログラム:Strict Modeの挙動を確認する
以下のコードをコピーして、コンポーネント内でuseEffectの動きを確認してみてください。Strict Modeが有効な場合、コンソールには「マウントされました」が2回表示されるはずです。
import React, { useEffect } from ‘react’;
function DebugComponent() {
useEffect(() => {
// 開発環境のStrict Modeでは、ここが2回実行されます
console.log(‘副作用が実行されました’);
// クリーンアップ関数の重要性
// ここにタイマーの停止や通信のキャンセル処理を書くのが正解です
return () => {
console.log(‘クリーンアップが実行されました’);
};
}, []);
return
;
}
export default DebugComponent;
応用・注意点:現場で陥りやすい罠
Strict Modeで2回実行されることで、「APIを叩く回数が増えて困る」というケースがあります。しかし、これは「APIを呼ぶ場所が適切ではない」というサインです。
1. クリーンアップの徹底:useEffect内でタイマーをセットしたら、必ずreturnでclearIntervalを行う癖をつけましょう。
2. 純粋関数の意識:コンポーネントのレンダリング内で、外部変数や状態を直接変更するのは避けましょう。Reactは「同じ入力には常に同じ結果を返す(純粋関数)」ことを期待しています。
3. 本番環境は安心:Strict Modeはあくまで開発用の機能です。ビルド後の本番環境では2回実行されることはありませんので、安心してください。
もし「どうしてもログが鬱陶しい」と感じても、決してStrict Modeを削除しないでください。それは、あなたのコードの品質を守るための重要なフィルターなのです。まずは、ログが2回出ても問題ないように「クリーンアップ処理」を正しく書く練習から始めてみましょう。

コメント