🎉

[React]useEffectはコンポーネントがレンダリング後に副作用として動作

2023/02/26に公開

概要

  • Reactのフックの1つであるuseEffectの使い方を記載します。
  • この記事の内容はQiitaでも記載しています。

My Qiita
https://qiita.com/ayumu__/items/ed056817ea94e9423976

目次

  1. React-hooksとは
  2. useEffectとは
  3. useEffectの使い方

1.React-hooksとは

React-hooksは、クラスを使わずに、Reactのstateを管理したり、ライフサイクルに応じた処理の実装ができる機能のことを指します。React-hooksを活用することで、簡潔で読みやすいコードを書くことができます。hooksには機能が異なるものが幾つか存在します。

公式ドキュメント:フック早わかり
https://ja.reactjs.org/docs/hooks-overview.html

公式ドキュメントのフック早わかりにもあるようにフックには異なる機能を持つ複数のフックが存在し、例えば、ステートフックと呼ばれるuseStateや、副作用フックと言われるuseEffectがあります。
今回は服作業フックのuseEffectの使い方例を紹介します。

2.useEffectとは

useEffectは、React-hooksの1つのフックであり、コンポーネントがレンダリングされた後に副作用を実行するために使用されます。副作用とは、例えばAPIからデータを取得する、タイマーをセットする、DOMノードを操作するなど、コンポーネントの状態を変更することのできる処理のことを指します。
useEffectは以下のような形式で使用されます。

useEffect(() => {
  // 副作用を実行する処理を記述する
}, [依存配列]);

上記の例において、第1引数には、副作用を実行するための関数を渡します。この関数は、コンポーネントがマウント/アップデートされた後、アンマウントされる前に実行されます。
第2引数には、副作用を実行する際に参照する値の配列(依存配列)を渡します。この配列が指定された場合、この配列内の値が変更された場合のみ副作用が再度実行されます。
配列が指定されなかった場合、すべてのレンダリングの後に副作用が実行されます。

useEffectの戻り値は、クリーンアップ関数を返すことができます。このクリーンアップ関数は、コンポーネントがアンマウントされる前、またはアップデートされる前に実行されます。この関数は、副作用を解除するための処理を記述することができます。ただし、クリーンアップが必要ない場合は、戻り値を指定する必要はありません。

利用する上での注意点としては、useEffectによる無限ループがあります。useEffectのコールバック関数でステートを変更した際に第2引数にstateを渡すような記述をすると、無限ループが発生します。この対策として、useEffectの第2引数は、[]などと記述しておくほうが良さそうです。

3.useEffectの使い方

useEffectの使い方として、例を2つ示します。

例1:useEffectを活用しAPIからデータを取得し、コンポーネントの状態を変更

コード
import { useState, useEffect } from 'react';
import axios from 'axios';

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

  useEffect(() => {
    // APIからユーザーデータを取得する
    axios.get('https://UriIsHere/users')
      .then((response) => {
        // 取得したデータをコンポーネントの状態にセットする
        setUsers(response.data);
      })
      .catch((error) => {
        console.log(error);
      });
  }, []);

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

解説

上記のコードでは、useStateフックを使用して、usersという名前の状態を定義し、setUsers関数を使用して、状態を更新しています。
useEffectフックを使用して、コンポーネントがマウントされた後、axiosライブラリを使用してAPIからユーザーデータを取得し、setUsers関数を使用して、コンポーネントの状態を更新します。
useEffectの第2引数には、[]を渡しているため、コンポーネントがマウントされた後に1回だけ副作用が実行されるようになっています。

取得したusersのデータは、map関数を使用してui表示させています。具体的には、users.mapメソッド経由でリスト形式で表示しています。ここで、mapメソッドを使用することで、users配列内の各ユーザーに対して、<li>要素を生成しています。map関数を使用する際には、keyを使ってidがユニークであることを示す必要があります。

例2:AWS AmplifyのuseAuthenticatorフックを使用して認証されたユーザ情報をuseEffectで処理

コード
  const { user } = useAuthenticator((context) => [context.user]);
  useEffect(() => {
    async function fetchDataFromDB() {
      try {
        const user = await Auth.currentAuthenticatedUser(); 
        const res = await getDataFromDB(user); 
        setFetchData(res); 
      } catch (error) {
        console.log(error);
      }
    }
    fetchDataFromDynamoDB();
  }, []);
解説

まず、コード全体の概要として、上記のコードはAWS AmplifyのuseAuthenticatorフックを使用して認証されたユーザーの情報を取得し、そのユーザーに関連するデータをデータベースから取得する例です。importや他の処理は排除していることに注意が必要です。
それでは、最上部から解説していきます。

useAuthenticator((context) => [context.user]);

まず、useAuthenticatorフックは、認証情報を提供するために必要なコンテキストを提供するフックであり、context.userプロパティを通じて認証されたユーザーの情報を取得できます。
例1同様、useEffectフックは、コンポーネントがマウントされた後に1回だけ実行されます。これは、第2引数が[]を指定しているためです。
続いて、fetchDataFromDBという非同期関数が定義され、その中で、Auth.currentAuthenticatedUser()メソッドを使用して、認証されたユーザーの情報を取得し、その情報を使用して、getDataFromDB関数を呼び出します。
これによって認証されたユーザ情報を基にgetメソッドでデータを取得することができます。この場合、主キーなるものでデータをfetchしに行っています。また、その結果をres変数に格納しています。
最後に、setFetchData関数を使用して、res変数をコンポーネントの状態に保存します。
つまり、このような実装をすることで、ユーザ認証後にその認証情報を用いたgetメソッドで、DBから値を取ってくるような実装が可能になります。

おわりに

  • useEffectの使い方について備忘させていただきました。
  • しれっとuseStateも使いました。
  • 他のhooksについても使いこなせるようになりたいです。

Discussion