1. ホーム
  2. 記事一覧
  3. Reactの基本、useEffectを理解しよう

2024.08.17

Reactの基本、useEffectを理解しよう

はじめに

Reactは、ユーザーインターフェースを構成するためのJavaScriptライブラリです。近年では、ウェブアプリケーションやモバイルアプリケーションのインターフェースを作成するために、多くの開発現場で使用されています。Reactを学ぶことで、モダンなウェブ開発のスキルを身につけることができるため、フロントエンドエンジニアを目指す上で必須のスキルと言っても過言ではありません。

フロントエンドエンジニアを目指す方や、初めてReactを学ぶ方に向けて、この記事ではReact HooksのuseEffectについて解説します。useEffectの仕組みは少し複雑で初学者の方にとって難しく感じるかもしれませんが、Reactでの開発では必須の技術となります。useEffectの基本を押さえておくことで、これからのReact学習の理解度が深まります。基本を学び、フロントエンドエンジニアへの道を進んでいきましょう!

この記事について

目的

  • useEffectについて知る
  • useEffectの副作用を理解する

対象者

  • 初学者の方
  • Reactの勉強を最近始めた方
  • useEffectに苦手意識のある方

Reactの基本について

Reactの基本の説明はこの記事では省略しています。基本や環境構築方法などを知りたい方は、下記のページをご覧ください。

https://envader.plus/article/341

useEffectについて

useEffectはReactフックの1つであり、コンポーネントがレンダリングされた後に、何らかの副作用を実行するために使用されます。例えば外部からコンポーネントへAPIデータの取得、DOMの操作、コンポーネント内にタイマーを設置したい場合などに利用します。これは、コンポーネントが画面に表示された後に、何らかの処理の実行を操作することができることを意味します。

Reactにおける副作用とは何か

Reactにおける「副作用」という概念は、少し難しく感じるかもしれませんが、ゆっくりと順を追って確認していきましょう。

プログラミングにおいての副作用とは、計算や関数の実行結果が、主たる目的以外に生じる影響のことを指します。例えば、変数の値を変更したり、外部のシステムとやり取りすることが副作用にあたります。Wikipediaでは、副作用について以下のように説明されています。

プログラミングにおいて、式の評価による作用には、主たる作用とそれ以外の副作用(side effect)とがある。 式は、評価値を得ること(※関数では「引数を受け取り値を返す」と表現する)が主たる作用とされ、それ以外のコンピュータの論理的状態(ローカル環境以外の状態変数の値)を変化させる作用を副作用という。 引用:Wikipedia

これを踏まえて、Reactにおける副作用を見ていきましょう。

Reactのコンポーネントについて

まず、Reactのコンポーネントについて考えます。Reactのコンポーネントは通常、状態やプロパティ(props)にもとづいて画面を描画(レンダリング)します。状態やプロパティに変更があると、そのコンポーネントは再レンダリングされ、UIが更新されます。ReactコンポーネントはUIを表示するためにあり、状態やプロパティを受け取り、画面のUIを表示するためのレンダーコード(JSX)を返すシンプルな構造です。このコンポーネントがUIを構築するためにJSXを返すことが、Reactコンポーネントにおける「主たる作用」です。

また、React公式では、レンダープロセスは「純粋である必要がある」と説明されています。純粋とは、受け取った状態やプロパティ(入力)に対して、常に同じUI(出力)を返すことを指し、副作用がないことを意味します。レンダリングはUIの描画に集中し、その他の外部とのやり取りや状態の変更は含まないことを推奨しています。

副作用について

次に副作用について考えます。Reactコンポーネントが画面の表示以外の何かを行うとき、これを「副作用」と呼びます。例えば、イベントハンドラでボタンがクリックされたときに、APIを呼び出してデータを取得したり、画面に表示される情報を更新する操作は、副作用を含みます。その他に、以下のような項目が副作用にあたります。

  • 外部のAPIからデータを取得して、コンポーネントに表示
  • ユーザーがフォームに入力した内容をサーバーに送信して保存
  • 数秒ごとにカウントを増やしたりするタイマーを設定
  • コンポーネントが表示されたことを記録するために、console.log()でコンソールにメッセージを表示

これらの操作は、コンポーネントが画面に表示されるだけでなく、データの取得や外部サービスとの通信などが必要な場合に行われます。Reactにおける副作用とは、コンポーネントが主たる作用である画面表示以外に行う、外部システムとのやり取りや、内部状態の変更を含む操作を指します。これにより、最終的に画面の内容が変わることもありますが、その実行は通常のレンダリングプロセスとは異なるタイミングで行われるため「副作用」として区別されます。

なぜ副作用が必要なのか?

アプリケーションを作るとき、単に文字やボタンを表示するだけでなく、ユーザーが何かを入力したり、他のユーザーとデータを共有したり、外部の情報を表示するなど、動的に画面の表示内容を変える必要があります。これには、外部とのやり取りが不可欠であり、これが副作用の役割です。

たとえば、天気予報アプリを作るとします。アプリが表示されるたびに、最新の天気を外部のAPIから取得して、ユーザーに表示する必要があります。この「最新の天気をAPIから取得する」操作が副作用です。

副作用はどのように管理する?

Reactでは、useEffectの仕組みを使って副作用を管理します。useEffectを使うことで、「コンポーネントがレンダリングされた後に、この副作用を実行する」といった指示をReactに与えることができます。

また、副作用には「クリーンアップ」が必要な場合があります。たとえば、あるコンポーネントがタイマーをセットしているとき、そのコンポーネントが画面から消えるときにはタイマーを止める必要があります。これを「クリーンアップ」と呼びます。

副作用の影響を考える

副作用は非常に便利ですが、適切に管理しないとバグや予期しない動作を引き起こすことがあります。たとえば、副作用の実行を適切に設定しないと、無限ループが発生してしまうことがあります。これが起こると、アプリケーションが非常に遅くなり、反応が悪くなるなど、ユーザー体験が大きく損なわれる可能性があります。

useEffectの3つのライフスタイル

コンポーネントが特定の状態の際に、副作用の実行をReactに指示し管理できると知りましたが、このプロセスを理解するには、useEffectの3つのライフサイクルを把握することが大切です。この3つのライフサイクルとは、コンポーネントが最初にレンダリングされる「マウント」、コンポーネントや状態(state)が変更されたときの「更新」、コンポーネントが非表示になった際の「アンマウント」です。

「マウント」と「更新」のタイミングは、依存関係配列によって制御されます。依存関係配列は、useEffectの第二引数として渡します。

アンマウント時には、クリーンアップ関数はコンポーネントが非表示になった際に、または依存関係が変更される前に実行されます。依存関係が変更される前に実行とは、useEffectの第二引数として渡される依存関係配列が変更された場合、以前の副作用をクリーンアップしてから、新しい依存関係にもとづいて再度副作用を実行されます。

useEffect(() => {
	...
}, [依存関係配列])
  • マウント時の実行

    最初にコンポーネントが画面に表示された後にuseEffectを実行する際は、空の依存関係配列を使用します。

useEffect(() => {
	// マウント時の処理
}, [])
  • 更新時の実行

    コンポーネントの状態(state)が変化し、再レンダリングが行われた後にuseEffectを実行するには、該当の状態変数を依存関係配列に指定します。複数の状態変数を指定することも可能です。

useEffect(() => {
	// 状態変化時の処理
}, [状態変数])
  • アンマウント時の実行

    コンポーネントが非表示になった際に、クリーンアップ関数を実行するには、useEffect内で returnの後にクリーンアップ処理を定義します。

useEffect(() => {
	// マウントおよび更新時の処理
	return () = {
		// アンマウント時のクリーンアップ処理
	}
}, [])

useEffectの実行管理の使用事例

Reactのコンポーネントにおける副作用を、3つのライフサイクルに応じて管理する方法を学びました。これがどのように役立つかを、先ほど例に挙げた天気予報アプリを例に確認しましょう。

  • マウント時の実行

    まず、useEffectのマウント時の処理についてです。東京の天気を表示するコンポーネントがあるとします。このコンポーネントが画面に表示されたとき、外部の天気予報APIからデータを取得したい場合は、useEffectと空の依存関係配列を使用して、「コンポーネントが表示された後にAPIからデータを取得する」というマウント時の処理を実装します。

  • 更新時の実行

    次に、useEffectの更新時の処理についてです。東京の天気を表示するコンポーネントに、他の地域の天気を表示する機能を追加したとします。たとえば、大阪を選んでボタンを押した後に、APIから大阪の天気データを取得したい場合、useEffectと特定の状態変数を依存関係配列に指定します。指定した状態変数が変更された場合、「コンポーネントの表示内容を東京から大阪に変更した後に、APIから大阪の天気データを取得する」という更新時の処理が実行されます。

  • アンマウント時の実行

    最後に、アンマウント時の処理についてです。天気予報アプリ内のコンポーネントに、一定の間隔でランダムに天気予報を変更する機能を実装したとします。このコンポーネントが非表示になった際には、「一定時間で天気を変更する」という機能をクリアするクリーンアップ処理を実装します。

useEffect内にAPIコールを行うコードを記述し、依存関係配列に適切な指定をすることで、特定のタイミングでデータ取得が行われ、取得したデータが画面に表示されるようになります。そして、アンマウント時の処理が必要な場合は、クリーンアップ処理を実装してメモリリークを防止します。このようにuseEffectを使用することで、Reactコンポーネントの副作用を効果的に管理することが可能です。

useEffectの使い方

ここまでの解説を踏まえて、useEffectの使い方を確認しましょう。まず、ReactからuseEffectをインポートします。次に、コンポーネント内でuseEffectを呼び出し、副作用を実行する関数(セットアップ関数)と、それに関連するクリーンアップ処理(クリーンアップ関数)を渡します。また、useEffectの実行タイミングを制御するための依存関係配列も引数として渡します。

インポート文

ファイルのトップレベルで以下のインポート文を記述します。これにより、そのファイル内でuseEffectが使用可能になります。

import { useEffect } from 'react';

useEffectの宣言と実装例

useEffectを使用する際は2つの引数を渡します。

  • セットアップ関数およびクリーンアップ関数

    コンポーネントがレンダリングされたときに実行される処理と、コンポーネントがアンマウントされるときに実行されるクリーンアップ処理を定義します。

  • 依存関係配列

    useEffectが再実行されるタイミングを制御します。特定の状態変数を指定するか、再実行を避けるために空の配列を指定します。

コンポーネントが初めてレンダリングされると、副作用を実行するセットアップ関数が実行されます。依存関係配列が空の場合、この関数は一度だけ実行されます。コンポーネントがアンマウントされるときには、クリーンアップ関数が実行されます。

useEffect(() => {
	// 副作用を実行するセットアップ関数をここに記述します。
	return () => {
	// クリーンアップ関数の処理をここに記述します。
	}
}, [状態変数、または空の配列]);

useEffectを実際に使用してみよう

ここまでuseEffectの基本について解説してきました。実際にコードを試してuseEffectの理解を深めていきましょう。

このハンズオンでは以下のカウントアップアプリを作成します。

ハンズオンを手軽に試したい方には、以下のサイトがおすすめです。Reactの環境構築が不要で、ブラウザ上でコードをすぐに試すことができます。

クリーンアップ関数を使用したカウントアップアプリの作成

クリーンアップ関数を使用したアプリの例として、カウントアップアプリを作成します。このアプリでは、1秒ごとにカウントが増加しますが、コンポーネントが非表示になった際にタイマーをクリアする必要があります。これにより、不要なメモリの使用を防ぐことができます。以下がその実装例です。

// App.jsx

import { useEffect, useState } from 'react';
import './App.css';

function App() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    const intervalId = setInterval(() => {
      setCount(prevCount => prevCount + 1);
    }, 1000);

    // アンマウント時にタイマーをクリア
    return () => {
      clearInterval(intervalId);
      console.log('Timer cleared');
    };
  }, []);

  return (
    <div>
      <h2>Timer: {count} seconds</h2>
    </div>
  );
}

export default App;

コードの解説

  • useStateフック

    このuseStateフックはcountという状態を作成し、カウントアップの値を管理します。

  • useEffectフック

    1秒ごとにsetIntervalでカウントが増えるように設定しています。また、クリーンアップ関数としてclearIntervalを使い、コンポーネントが非表示になった際にタイマーを停止します

  • return内の処理

    これはクリーンアップ関数で、コンポーネントがアンマウントされる際に実行されます。

結果の確認

コードを編集し、アプリを実行すると、画面には1秒ごとにカウントが増加する以下のようなタイマーが作成できているかと思います。

このアプリを通じて、useEffectのライフサイクル管理とクリーンアップ関数の役割を実際に体験できます。

この記事で学んだこと

ここまでuseEffectについて、その基本と実際の使い方を学びました。簡単に振り返ってみましょう。

  • useEffectについて

    useEffectはReactのフックの1つであり、コンポーネントがレンダリングされた後に副作用を実行するために使用されます。たとえば、コンポーネントが画面に表示された後に外部APIからデータを取得して画面に表示する、といった処理が可能になります。

  • useEffectの3つのライフスタイル

    useEffectを使用することで、コンポーネントのライフサイクルに応じた副作用の実行をReactに指示し、管理することが可能です。これらのライフサイクルには、コンポーネントが最初にレンダリングされる「マウント」、コンポーネントや状態(state)が変更されたときの「更新」、コンポーネントが非表示になった際の「アンマウント」が含まれます。useEffectがどのように実行されるかは、useEffectの第二引数として渡す依存関係配列やクリーンアップ関数よって制御されます。

参考資料

以下のリンクは、この記事で説明した手順や概念に関連する参考資料です。より詳しく学びたい方は、ぜひご参照ください。

【番外編】USBも知らなかった私が独学でプログラミングを勉強してGAFAに入社するまでの話

IT未経験者必見 USBも知らなかった私が独学でプログラミングを勉強してGAFAに入社するまでの話

プログラミング塾に半年通えば、一人前になれると思っているあなた。それ、勘違いですよ。「なぜ間違いなの?」「正しい勉強法とは何なの?」ITを学び始める全ての人に知って欲しい。そう思って書きました。是非読んでみてください。

「フリーランスエンジニア」

近年やっと世間に浸透した言葉だ。ひと昔まえ、終身雇用は当たり前で、大企業に就職することは一種のステータスだった。しかし、そんな時代も終わり「優秀な人材は転職する」ことが当たり前の時代となる。フリーランスエンジニアに高価値が付く現在、ネットを見ると「未経験でも年収400万以上」などと書いてある。これに釣られて、多くの人がフリーランスになろうとITの世界に入ってきている。私もその中の1人だ。数年前、USBも知らない状態からITの世界に没入し、そこから約2年間、毎日勉学を行なった。他人の何十倍も努力した。そして、企業研修やIT塾で数多くの受講生の指導経験も得た。そこで私は、伸びるエンジニアとそうでないエンジニアをたくさん見てきた。そして、稼げるエンジニア、稼げないエンジニアを見てきた。

「成功する人とそうでない人の違いは何か?」

私が出した答えは、「量産型エンジニアか否か」である。今のエンジニア市場には、量産型エンジニアが溢れている!!ここでの量産型エンジニアの定義は以下の通りである。

比較的簡単に学習可能なWebフレームワーク(WordPress, Rails)やPython等の知識はあるが、ITの基本概念を理解していないため、単調な作業しかこなすことができないエンジニアのこと。

多くの人がフリーランスエンジニアを目指す時代に中途半端な知識や技術力でこの世界に飛び込むと返って過酷な労働条件で働くことになる。そこで、エンジニアを目指すあなたがどう学習していくべきかを私の経験を交えて書こうと思った。続きはこちらから、、、、

note記事3000いいね超えの殿堂記事 今すぐ読む

エンベーダー編集部

エンベーダーは、ITスクールRareTECHのインフラ学習教材として誕生しました。 「遊びながらインフラエンジニアへ」をコンセプトに、インフラへの学習ハードルを下げるツールとして運営されています。

RareTECH 無料体験授業開催中! オンラインにて実施中! Top10%のエンジニアになる秘訣を伝授します! RareTECH講師への質疑応答可

関連記事