Reactクラスコンポーネントのライフサイクルメソッド一覧!初心者にもわかる完全ガイド
生徒
「Reactのクラスコンポーネントって、どんな流れで動いているんですか?」
先生
「クラスコンポーネントは、ライフサイクルメソッドという仕組みで“生まれてから消えるまで”の流れを管理しています。」
生徒
「ライフサイクルメソッド?なんだか難しそうですね…」
先生
「大丈夫ですよ。人の一生のように、“誕生→成長→終了”の3段階で考えると、とても分かりやすいです。それでは順番に見ていきましょう!」
1. ライフサイクルとは?
「ライフサイクル」とは、コンポーネントが画面に表示されてから消えるまでの流れを指します。Reactでは、この流れの中で特定のタイミングに処理を追加できる「ライフサイクルメソッド」が用意されています。
クラスコンポーネントには、次のような大きな3つのフェーズ(段階)があります。
- マウント(Mount):コンポーネントが画面に登場するとき
- 更新(Update):状態やプロパティが変わって再描画されるとき
- アンマウント(Unmount):コンポーネントが画面から消えるとき
この流れを理解することで、クラスコンポーネントを安全かつ正確に制御できます。
2. マウント(Mount)フェーズのメソッド
コンポーネントが初めて画面に表示されるときに呼ばれるメソッドです。
① constructor()
constructorは、コンポーネントが作られる直前に呼ばれます。初期状態(state)やメソッドのバインド(結びつけ)などをここで行います。
import React from "react";
class Hello extends React.Component {
constructor(props) {
super(props);
this.state = { message: "こんにちは!" };
}
render() {
return <h1>{this.state.message}</h1>;
}
}
export default Hello;
② componentDidMount()
componentDidMountは、コンポーネントが画面に描画されたあとに1回だけ実行されます。API通信や外部データの取得、イベント登録などに使います。
componentDidMount() {
console.log("コンポーネントが画面に表示されました!");
}
3. 更新(Update)フェーズのメソッド
このフェーズは、stateやpropsが変化したときに呼び出されます。つまり、データが変わって再描画される瞬間です。
① shouldComponentUpdate()
shouldComponentUpdateは、再描画の前に呼ばれます。ここでfalseを返すと描画を止めることができます。処理を軽くしたい場合に使います。
shouldComponentUpdate(nextProps, nextState) {
return nextState.count !== this.state.count;
}
② componentDidUpdate()
componentDidUpdateは、描画が完了した直後に呼ばれます。前回の値を比較して処理をしたいときに便利です。
componentDidUpdate(prevProps, prevState) {
if (prevState.count !== this.state.count) {
console.log("カウントが更新されました!");
}
}
4. アンマウント(Unmount)フェーズのメソッド
このフェーズは、コンポーネントが画面から消えるときに呼ばれます。
① componentWillUnmount()
componentWillUnmountは、コンポーネントが破棄される直前に実行されます。タイマーの停止、イベントリスナーの解除、通信の中断など、後片付けをここで行います。
componentWillUnmount() {
clearInterval(this.timer);
console.log("コンポーネントが削除されました");
}
5. その他の特殊メソッド
上記以外にも、クラスコンポーネントには特殊なメソッドがあります。
① static getDerivedStateFromProps()
propsの変更に応じてstateを更新するための静的メソッドです。副作用を伴わないため、通常はあまり多用しません。
static getDerivedStateFromProps(nextProps, prevState) {
if (nextProps.value !== prevState.value) {
return { value: nextProps.value };
}
return null;
}
② getSnapshotBeforeUpdate()
更新前のDOMの状態を取得できます。スクロール位置など、更新直前の情報を保持したいときに便利です。
getSnapshotBeforeUpdate(prevProps, prevState) {
return window.scrollY;
}
6. ライフサイクルの流れを図でイメージしよう
ライフサイクルメソッドの流れを「人の一生」に例えるとわかりやすいです。
- constructor → 「生まれる(準備)」
- componentDidMount → 「育つ(活動開始)」
- shouldComponentUpdate / componentDidUpdate → 「変化に対応(成長)」
- componentWillUnmount → 「片付けて終了(お別れ)」
この順番を覚えると、Reactのクラスコンポーネントの仕組みがスッキリ理解できます。
7. クラスコンポーネントの全体コード例
実際のクラスコンポーネントのライフサイクルをまとめると次のようになります。
import React from "react";
class LifeCycleDemo extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
console.log("constructor");
}
static getDerivedStateFromProps(props, state) {
console.log("getDerivedStateFromProps");
return null;
}
componentDidMount() {
console.log("componentDidMount");
}
shouldComponentUpdate(nextProps, nextState) {
console.log("shouldComponentUpdate");
return true;
}
getSnapshotBeforeUpdate(prevProps, prevState) {
console.log("getSnapshotBeforeUpdate");
return null;
}
componentDidUpdate() {
console.log("componentDidUpdate");
}
componentWillUnmount() {
console.log("componentWillUnmount");
}
render() {
console.log("render");
return (
<div>
<h1>カウント: {this.state.count}</h1>
<button onClick={() => this.setState({ count: this.state.count + 1 })}>
カウントアップ
</button>
</div>
);
}
}
export default LifeCycleDemo;
8. まとめて覚えるコツ
クラスコンポーネントは現在では関数コンポーネント+Hooksに置き換わることが多いですが、既存のReactコードを読むうえでは非常に重要です。まずは「いつ、どんなメソッドが呼ばれるのか」を流れで理解し、順番を意識して学びましょう。
まとめ
Reactのクラスコンポーネントにおけるライフサイクルメソッドについて、その全体像から具体的な各フェーズの役割まで詳しく解説してきました。フロントエンド開発において、コンポーネントがどのように生成され、更新され、そして破棄されるのかという「流れ」を正確に把握することは、バグの少ない高品質なアプリケーションを構築するための第一歩です。
現在、Reactの開発現場では「React Hooks」を用いた関数コンポーネントが主流となっています。しかし、長年運用されている大規模なプロジェクトや、特定の高度な最適化が必要なライブラリの内部実装などでは、依然としてクラスコンポーネントが重要な役割を果たしています。特にライフサイクルの概念は、関数コンポーネントの useEffect などを深く理解するための土台となる知識です。
Reactライフサイクルの3大フェーズを再確認
効率的なSEO対策を意識しつつ、重要なポイントを整理しましょう。Reactコンポーネントの挙動を制御するライフサイクルは、大きく分けて以下の3つのステージで構成されています。
- マウント(Mounting): コンポーネントのインスタンスが作成され、DOMツリーに挿入されるプロセス。初期化やAPIによる初回データ取得に不可欠。
- 更新(Updating): propsやstateの変更によって、コンポーネントが再レンダリングされるプロセス。ユーザーの操作に応じた動的な変化を管理。
- アンマウント(Unmounting): コンポーネントがDOMから削除されるプロセス。メモリリークを防ぐためのタイマー解除やイベントリスナーの削除など、後片付けの実行。
実践的なコード例:複数のメソッドを組み合わせたタイマーアプリ
これまでに学んだ componentDidMount や componentWillUnmount を組み合わせて、実際に動くタイマーコンポーネントのサンプルプログラムを見てみましょう。このように複数のライフサイクルを適切に使い分けることで、リソースを無駄にしない効率的なプログラミングが可能になります。
import React from "react";
class TimerApp extends React.Component {
constructor(props) {
super(props);
this.state = {
seconds: 0,
isRunning: true
};
this.timerId = null;
console.log("1. constructor: タイマーを初期化しました");
}
// コンポーネントがマウントされた直後にタイマーを開始
componentDidMount() {
console.log("2. componentDidMount: タイマーのカウントを開始します");
this.timerId = setInterval(() => {
this.setState(prevState => ({
seconds: prevState.seconds + 1
}));
}, 1000);
}
// 更新が必要かどうかを判定(SEOやパフォーマンス向上のための最適化)
shouldComponentUpdate(nextProps, nextState) {
// 5秒ごとにログを出すなど、特定の条件でのみ再描画を制御することも可能
return true;
}
// コンポーネントが更新された後の処理
componentDidUpdate(prevProps, prevState) {
if (prevState.seconds !== this.state.seconds) {
// 秒数が変わったときに何か特定の処理をしたい場合に記述
}
}
// コンポーネントが破棄される前にタイマーを停止(メモリリーク防止)
componentWillUnmount() {
console.log("3. componentWillUnmount: タイマーを破棄し、メモリを解放します");
clearInterval(this.timerId);
}
render() {
return (
<div className="p-4 border rounded bg-light">
<h3 className="text-primary">経過時間: {this.state.seconds}秒</h3>
<p>このコンポーネントを閉じると、背後で動いているタイマーも自動的に停止します。</p>
</div>
);
}
}
export default TimerApp;
エンジニアが意識すべきライフサイクルの注意点
Reactのクラスコンポーネントを扱う際、よくある落とし穴が「無限ループ」です。例えば、componentDidUpdate の中で条件分岐をせずに this.setState を実行してしまうと、更新が更新を呼び、ブラウザがフリーズする原因になります。必ず前回の prevProps や prevState と比較する処理を入れましょう。
また、SEOの観点からは、componentDidMount でデータをフェッチする場合、クライアントサイドレンダリング(CSR)特有の挙動を理解しておく必要があります。検索エンジンのクローラーがJavaScriptを実行して内容を読み取るまで、コンテンツが空の状態にならないよう、Next.jsなどのフレームワークを併用してサーバーサイドでのライフサイクル管理を行うのが現代のスタンダードです。
生徒
「先生、ライフサイクルメソッドの流れがようやく繋がりました!タイマーの例を見ると、componentWillUnmount での後片付けがどれだけ重要かよく分かりますね。」
先生
「その通りです。もしタイマーを止め忘れたら、画面から消えた後もブラウザの裏側でずっと処理が走り続けて、パソコンが重くなる原因になってしまいますからね。いわゆる『メモリリーク』という現象です。」
生徒
「なるほど…。あ、そういえば最近は関数コンポーネントが人気だと聞きましたが、あっちでも同じようなことができるんですか?」
先生
「良い質問ですね。関数コンポーネントでは useEffect というフック(Hook)を使って、これら全てのメソッドに近い動きを再現します。マウント、更新、アンマウントを一つの関数で管理できるので、コードがよりスッキリ書けるんですよ。」
生徒
「じゃあ、まずはこのクラスコンポーネントの基本の流れをしっかりマスターして、次は useEffect に挑戦してみようと思います!」
先生
「その意気です。基本が分かっていれば、新しい技術が出てきてもスムーズに対応できます。Reactの世界は奥が深いですが、一歩ずつ進んでいきましょうね。」