カテゴリ: React 更新日: 2026/02/04

Reactでライフサイクルを意識したデータ取得の流れを初心者向けに解説!

ライフサイクルを意識したデータ取得の流れ
ライフサイクルを意識したデータ取得の流れ

先生と生徒の会話形式で理解しよう

生徒

「先生、Reactでデータを取得するときってどこでやるんですか?」

先生

「Reactでは、コンポーネントのライフサイクルに合わせてデータ取得を行うと効率的です。」

生徒

「ライフサイクルって難しそうですが、具体的にはどういうことですか?」

先生

「簡単に言うと、コンポーネントが生まれるとき、更新されるとき、消えるときのタイミングに合わせて処理を実行できるということです。」

1. クラスコンポーネントでのデータ取得の流れ

1. クラスコンポーネントでのデータ取得の流れ
1. クラスコンポーネントでのデータ取得の流れ

クラスコンポーネントでは、データ取得は主にcomponentDidMountで行います。componentDidMountはコンポーネントが初めて画面に表示された直後に実行されるライフサイクルメソッドです。ここでAPIからデータを取得して状態を更新すると、初期表示のデータが正しく反映されます。


import React from "react";

class UserList extends React.Component {
  state = { users: [] };

  componentDidMount() {
    fetch("https://jsonplaceholder.typicode.com/users")
      .then(response => response.json())
      .then(data => this.setState({ users: data }));
  }

  render() {
    return (
      <ul>
        {this.state.users.map(user => (
          <li key={user.id}>{user.name}</li>
        ))}
      </ul>
    );
  }
}

export default UserList;
(コンポーネントが画面に表示された直後にAPIからユーザー情報を取得し、リストとして表示されます)

2. 関数コンポーネントでのデータ取得の流れ

2. 関数コンポーネントでのデータ取得の流れ
2. 関数コンポーネントでのデータ取得の流れ

関数コンポーネントでは、useEffectフックを使います。useEffectは副作用(サイドエフェクト)を処理するための関数で、画面に表示された直後にデータ取得処理を行うことができます。


import React, { useState, useEffect } from "react";

function UserList() {
  const [users, setUsers] = useState([]);

  useEffect(() => {
    fetch("https://jsonplaceholder.typicode.com/users")
      .then(response => response.json())
      .then(data => setUsers(data));
  }, []); // 空配列は初回のみ実行を意味します

  return (
    <ul>
      {users.map(user => (
        <li key={user.id}>{user.name}</li>
      ))}
    </ul>
  );
}

export default UserList;
(コンポーネントが初めて表示されたときにAPIからデータを取得し、ユーザーリストを表示します)

3. ライフサイクルを意識したデータ取得のポイント

3. ライフサイクルを意識したデータ取得のポイント
3. ライフサイクルを意識したデータ取得のポイント

データ取得の流れを効率的に行うには、ライフサイクルを意識することが重要です。ポイントは以下の通りです。

  • 初回レンダリング後にデータを取得する
  • 依存する値が変わったときのみデータを再取得する
  • コンポーネントが消えるときはクリーンアップを行う

例えば、ユーザーIDが変更されるたびにデータを再取得する場合、useEffectの依存配列にユーザーIDを入れます。


function UserDetail({ userId }) {
  const [user, setUser] = useState(null);

  useEffect(() => {
    let isMounted = true;
    fetch(`https://jsonplaceholder.typicode.com/users/${userId}`)
      .then(res => res.json())
      .then(data => {
        if (isMounted) setUser(data);
      });
    return () => {
      isMounted = false; // クリーンアップ
    };
  }, [userId]);

  if (!user) return <p>読み込み中...</p>;
  return <div>{user.name} ({user.email})</div>;
}
(ユーザーIDが変わるたびに新しいデータを取得し、コンポーネントが消えるときは前回の処理をキャンセルします)

4. データ取得の流れを意識した設計のメリット

4. データ取得の流れを意識した設計のメリット
4. データ取得の流れを意識した設計のメリット

ライフサイクルに沿ってデータ取得を設計すると、次のようなメリットがあります。

  • 無駄なAPIリクエストを減らせる
  • ユーザーに常に最新のデータを表示できる
  • コンポーネントのアンマウント時に後片付けができる
  • アプリのパフォーマンスと安定性が向上する

Reactではこのようにライフサイクルを意識してデータ取得を行うことで、効率的で安全なアプリを作ることができます。

まとめ

まとめ
まとめ

ここまでReactにおけるライフサイクルとデータ取得の重要性について詳しく解説してきました。Reactの開発において、コンポーネントが「いつ」「どのように」データを取得し、画面を更新するかという流れを理解することは、エンジニアとしてのスキルアップに欠かせないステップです。特に、現代のフロントエンド開発では、関数コンポーネントとuseEffectフックを用いた宣言的な記述が主流となっています。

ライフサイクルを意識した開発の肝は、「副作用(Side Effects)の管理」にあります。APIからのデータ取得、タイマーの設定、手動でのDOM操作などはすべて副作用と呼ばれます。これらを適切に扱わないと、メモリリークが発生したり、無限ループに陥ってブラウザの動作が重くなったりするリスクがあります。

さらに、昨今のフロントエンド技術の進化により、データの取得方法も多様化しています。標準的なfetch APIだけでなく、Axiosのようなライブラリの活用、さらにはReact Query (TanStack Query)SWRといったキャッシュ管理を伴う高度なデータフェッチライブラリの導入も検討されるようになっています。しかし、それらすべての根底にあるのは、Reactのライフサイクルという基本原則です。

応用編:エラーハンドリングとローディング表示の実装

実際の現場で使われるコードでは、単にデータを取得するだけでなく、通信中の「ローディング状態」や、通信に失敗した際の「エラー表示」をユーザーに見せる必要があります。これを実現することで、ユーザーエクスペリエンス(UX)は劇的に向上します。以下に、より実戦的なサンプルプログラムを紹介します。


import React, { useState, useEffect } from "react";

function AdvancedUserList() {
  const [users, setUsers] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    const fetchData = async () => {
      try {
        setLoading(true);
        const response = await fetch("https://jsonplaceholder.typicode.com/users");
        if (!response.ok) {
          throw new Error("データの取得に失敗しました。");
        }
        const data = await response.json();
        setUsers(data);
      } catch (err) {
        setError(err.message);
      } finally {
        setLoading(false);
      }
    };

    fetchData();
  }, []);

  if (loading) return <p>データを読み込んでいます。しばらくお待ちください...</p>;
  if (error) return <p style={{ color: "red" }}>エラー:{error}</p>;

  return (
    <div className="user-container">
      <h3>ユーザー一覧(最新)</h3>
      <ul className="list-group">
        {users.map(user => (
          <li key={user.id} className="list-group-item">
            <strong>{user.name}</strong> - {user.company.name}
          </li>
        ))}
      </ul>
    </div>
  );
}

export default AdvancedUserList;
(データ取得中は「読み込んでいます」という案内が表示され、成功すると会社名付きのユーザーリストが、失敗するとエラーメッセージが表示されます)

SEOとパフォーマンスを考慮したReact開発

Reactのアプリケーションにおいて、検索エンジン最適化(SEO)を意識する場合、クライアントサイドレンダリング(CSR)だけでなく、サーバーサイドレンダリング(SSR)や静的サイト生成(SSG)が重要視されます。Next.jsなどのフレームワークを使用することで、サーバー側でデータをプリフェッチし、HTMLとして出力することが可能になります。これにより、クローラーがサイトの内容を正しく読み取りやすくなり、検索順位の向上に寄与します。

しかし、どの手法を選択するにせよ、Reactのコンポーネントがマウントされた後にデータを非同期で取得するという基本パターンは、動的なコンテンツ表示において必須の知識です。まずはuseEffectを完璧に使いこなし、依存配列(Dependency Array)の仕組みを理解することから始めましょう。

先生と生徒の振り返り会話

生徒

「先生、今回のまとめでコードが少し複雑になりましたね。でも、ローディングやエラーの処理があるほうが、実際のウェブサイトっぽくて安心します!」

先生

「その通りです。実際の開発では、ネットワークが常に安定しているとは限りません。ユーザーに『今何が起きているか』を伝えるための状態管理は、Reactで最も大切なことの一つなんですよ。」

生徒

useEffectの最後にある空の配列 [] を忘れると、無限にAPIを叩き続けてしまうという話を聞きましたが、本当ですか?」

先生

「よく知っていますね。依存配列を指定しないと、レンダリングのたびに実行されてしまいます。APIを叩いてステートを更新すると、またレンダリングが走る。その繰り返しで無限ループになってしまうんです。だからこそ、ライフサイクルの理解が必要なんです。」

生徒

「なるほど。依存配列に変数を入れるときは、その変数が変わった時だけやり直したいときですね。例えば、検索キーワードが変わった時とか。」

先生

「素晴らしい理解です!さらに応用として、クリーンアップ関数を使って、前のリクエストをキャンセルするような書き方も覚えると、さらに中級者へと近づきますよ。コンポーネントが消える時に、中途半端な処理を残さないことが、バグの少ない綺麗なコードへの近道です。」

生徒

「奥が深いですね……。でも、Reactでのデータ取得の流れがイメージできるようになりました。まずは自分で簡単なプロフィールカードを作って、APIから自分の情報を取ってくる練習をしてみます!」

先生

「その意気です。実際に手を動かして、エラーにぶつかることが一番の勉強になります。もし困ったら、またライフサイクルの基本に戻って考えてみましょう。」

本記事では、Reactのクラスコンポーネントから最新の関数コンポーネントにおけるデータ取得の流れ、そして実用的なエラーハンドリングまでを解説しました。ライフサイクルをマスターすることは、Reactエンジニアとしての第一歩です。この記事が、皆さんのコーディングライフに少しでも役立てば幸いです。

カテゴリの一覧へ
新着記事
New1
React
Reactコンポーネントの再利用と分割を完全マスター!初心者でもわかるコンポーネント設計
New2
React
ReactでAxiosインターセプターの使い方を完全ガイド!初心者でもわかるリクエストとレスポンスの処理方法
New3
React
JSXの書き方!初心者でもわかるReactタグと属性の基本ルール解説
New4
React
ReactとDockerを使った開発環境構築の基本を徹底解説!初心者でもわかるReactとDockerの連携方法
人気記事
No.1
Java&Spring記事人気No1
React
ReactでonChangeイベントを使ってフォーム入力値を管理する方法を初心者向けに解説
No.2
Java&Spring記事人気No2
React
ReactとTypeScriptの環境構築をやさしく解説!Viteとtsconfigの設定も丁寧に紹介
No.3
Java&Spring記事人気No3
React
Reactのイベントハンドリングのアンチパターンまとめ!初心者でもわかる注意点
No.4
Java&Spring記事人気No4
React
Reactのカスタムフックの作り方を完全ガイド!再利用可能なロジックを切り出す仕組み
No.5
Java&Spring記事人気No5
React
ReactでFetch APIのローディング状態を管理する方法|初心者にもわかる解説
No.6
Java&Spring記事人気No6
React
ReactのuseStateとuseEffectでよくあるエラーと解決方法ガイド!初心者でもわかるReactフック
No.7
Java&Spring記事人気No7
React
Reactでファイルアップロードを実装する方法を解説!Fetch APIで画像やPDFを送る仕組みを初心者向けに紹介
No.8
Java&Spring記事人気No8
React
create-react-appでReactプロジェクトを作成する手順を初心者向けに完全解説!