Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【ITニュース解説】Coding Challenge Practice - Question 19

2025年09月29日に「Dev.to」が公開したITニュース「Coding Challenge Practice - Question 19」について初心者にもわかりやすく解説しています。

作成日: 更新日:

ITニュース概要

Reactコンポーネントがマウントされているか判定するカスタムフック「useIsMounted」の実装方法を解説。useRefでマウント状態を管理し、useEffectでマウント時にtrue、アンマウント時にfalseと更新する。これにより、非同期処理中でもコンポーネントの状態を正確に把握できる。

出典: Coding Challenge Practice - Question 19 | Dev.to公開日:

ITニュース解説

Reactを使ってWebアプリケーションを作る際、ユーザーインターフェースを構成する部品を「コンポーネント」と呼ぶ。このコンポーネントが今、ブラウザの画面に表示されているのか、それとも表示されていないのかを知ることは、アプリケーションの動作を安定させる上で非常に大切だ。特に、インターネットを通じてデータを受け取るような非同期の処理を行っている最中に、その処理結果を表示するはずだったコンポーネントが画面から消えてしまう(これを「アンマウントされる」と呼ぶ)と、エラーが起きることがある。例えば、存在しないコンポーネントに対して「この部分を更新してください」と指示してしまうような状況だ。このような潜在的な問題を未然に防ぎ、安全にコンポーネントの状態を管理するために、「useIsMounted」という特別なフック(Reactの機能)が開発された。

このuseIsMountedフックは、コンポーネントが画面に表示されている状態、つまり「マウントされている」状態であるかどうかを正確に判断するための仕組みを提供する。Reactには「カスタムフック」という便利な機能があり、これは複数のコンポーネントで繰り返し使いたい処理や状態管理のロジックを、再利用可能なひとまとまりのコードとして定義できるものだ。useIsMountedもその一つで、コンポーネントがマウントされた瞬間からアンマウントされる瞬間まで、その状態を追跡する役割を担う。

このフックの核となるのは、Reactの「useRef」というフックだ。useRefは、コンポーネントが画面上で再描画される「再レンダリング」が起きても、その中に保存している値を変更されずに保持し続けることができる特別な「箱」のようなものだと考えると良い。一般的なJavaScriptの変数を使うと、コンポーネントが再レンダリングされるたびに、その変数は初期値に戻ってしまう。しかし、useRefで作成した参照オブジェクトは、その中の.currentというプロパティを通じてアクセスされる値を、コンポーネントのライフサイクルを通じて永続的に保持し続ける。useIsMountedフックでは、まずconst isMounted = useRef(false);というコードでisMountedという参照オブジェクトを作り、その中の.currentプロパティの初期値をfalseに設定する。これは、コンポーネントがまだ画面に表示されていない、マウント前の状態を表す。

次に、コンポーネントが実際に画面に表示された、まさにそのタイミングを検出するために、Reactの「useEffect」というフックを利用する。useEffectは、コンポーネントが生成されたり、更新されたり、破棄されたりといった「ライフサイクル」の特定の段階で、指定した処理を実行するためのフックだ。useEffectには、実行したい関数と、その関数を再実行する条件を指定する依存配列を渡す。今回のケースでは、依存配列に[](空の配列)を渡すことで、useEffectの中の処理は、コンポーネントが最初にマウントされた時、つまり画面に表示された時に一度だけ実行されるように設定されている。

このuseEffectの内部で、isMounted.current = true;という処理が実行される。この行は、コンポーネントが画面に正常に表示され、マウントが完了した瞬間に、isMounted参照オブジェクトの.currentの値をtrueに変更することを意味する。これにより、isMounted.currentの値を確認すれば、そのコンポーネントが現在画面に存在しているかどうかをいつでも判断できるようになる。

さらに、useEffectには、コンポーネントが画面から取り除かれる「アンマウント」のタイミングで特定の処理を実行できる「クリーンアップ関数」という仕組みが用意されている。これは、useEffectに渡した関数が別の関数を返り値として返すことで定義される。具体的には、return () => { isMounted.current = false; }というコードがクリーンアップ関数だ。このクリーンアップ関数は、useEffectが次回の実行を迎える前か、あるいはコンポーネントがアンマウントされる直前に自動的に実行される。useEffectの依存配列が空の[]であるため、このクリーンアップ関数はコンポーネントがアンマウントされる直前に一度だけ実行されることになる。その中でisMounted.currentの値をfalseに設定することで、コンポーネントが画面から消えたことを正確に記録し、それ以降はそのコンポーネントがマウントされていないことを明確にする。

このuseIsMountedフックが最終的に返すのは、return () => isMounted.current;という関数だ。直接isMounted.currenttrueまたはfalseという値を返すのではなく、その値を取得するための関数を返すのは、非同期処理との連携を考慮しているためだ。例えば、データをインターネットから取得する処理(非同期処理)を開始した後、その処理が完了するまでに時間がかかるとする。その間にユーザーが別のページに移動してしまい、元のコンポーネントがアンマウントされてしまう可能性がある。非同期処理が完了した際に、isMounted()というフックが返す関数を呼び出すことで、その時点でコンポーネントがまだマウントされているかどうかを安全に確認できる。もしisMounted()falseを返せば、そのコンポーネントはもう画面にないので、無理に状態を更新しようとせず、処理を中止するといった判断が可能になる。

このように、useIsMountedフックは、useRefを使ってマウント状態を永続的に保持し、useEffectを使ってコンポーネントのマウントとアンマウントのタイミングを正確に捉えることで、Reactアプリケーションにおける状態管理をより安全で堅牢なものにする。特に非同期処理を多用する現代のWebアプリケーション開発において、この種のフックは予期せぬエラーを防ぎ、アプリケーション全体の安定性を向上させるための非常に有効な手段となる。開発者はこのフックを利用することで、コンポーネントが画面上に存在するかどうかの心配を減らし、より本質的な機能開発に集中できるようになる。

関連コンテンツ