33
25

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

React HooksのuseEffectで関数コンポーネントにライフサイクルを持たせる

Last updated at Posted at 2020-09-26

#目次

#はじめに
この記事では、React 16.8で導入されたHooksの機能の一つで、関数コンポーネントにライフサイクルメソッドを記述することのできる**useEffect**についてまとめています。現在ReactやHooksについて学習中の方の一助となれば幸いです。

###前提条件

  • Reactについて基本的な部分を理解している
  • Reactの基本についてはこちら
  • 「Hooksとは」についてはこちら

###環境

導入 version
react 16.13.1

#useEffectとは
**useEffect**は簡単にいうと、関数コンポーネントにライフサイクルメソッドを持たせるための機能です。
Hooksが導入される以前のReactでは、コンポーネントにライフサイクルメソッドを持たせるためにはクラスコンポーネントで記述する必要がありました。そのためはじめは関数コンポーネントで記述していたコンポーネントにライフサイクルイベントを追加する必要が出てきたときにわざわざクラスコンポーネントに変換しなければなりませんでした。このような問題を解決する手段としてuseEffectが利用できます。
useEffectでは、クラスコンポーネントで利用していたライフサイクルメソッドであるcomponentDidMountcomponentDidUpdatecomponentWillUnmountを1種類の関数で扱うことができます。

useEffect.001.png

またHooksがないときにはクラスコンポーネントと関数コンポーネントが混在していましたが、useEffectuseStateなどのHooksの機能を利用することで全てを関数コンポーネントで記述できるため、コード全体の可読性を高めることもできるでしょう。

#useEffectが呼び出されるタイミング

はじめに、関数コンポーネントがレンダリングおよび再レンダリングされるタイミングについて説明します。

初回レンダリングのタイミング

  • 関数コンポーネントがJSXとして読み込まれたとき

再レンダリングのタイミング

  • 親コンポーネントが再レンダリングされたとき
  • 受け取っているpropsに変化が生じたとき
  • 同コンポーネント内でuseStateを用いて定義している変数に変化が生じたとき

など

useEffectはこのようなレンダリングのタイミングで、自身で指定した任意の変数に変化が生じたときにコールバックとして記述した処理を実行します。

#useEffectの使い方

では実際にuseEffectの使い方について見ていきましょう。useEffectの書き方の違いで呼び出される条件が変化するので、しっかり抑えておきましょう。

###useEffectを利用するための基本
useEffectのインポート
何か別のライブラリを読み込む必要はなく、Reactからインポートして使用できます。

import React, { useEffect } from 'react';  // ここでuseEffectをインポートする

useEffectの基本構文
useEffectには第一引数としてコールバック関数、第二引数として任意の変数を格納する配列を記述します。
なお第二引数は省略可能です。

useEffect(() => {
  // 処理
}, [/* 任意の変数 */]);

以上がuseEffectを利用するための基本となります。

次に使用目的ごとに実際の記述方法について見ていきます。

###レンダリングされるタイミングで毎回実行する
初回レンダリング時および再レンダリングに毎回useEffectに渡したコールバック関数を実行する方法について説明します。
レンダリング時に毎回実行する方法は、useEffectの第二引数を省略することです。

App.js
import React, { useEffect } from 'react';

const App = () => {
  useEffect(() => {
    // 処理
  });  // 第二引数を省略

  return (
    // JSX
  );
};

※ ただし第二引数を省略し、レンダリング時に毎回実行するようにすると何らかの原因で無限ループに陥る可能性があるので極力このような記述はしない方がいいでしょう。

###初回レンダリング時のみ実行する
クラスコンポーネントのライフサイクルメソッドのcomponentDidMountのように初回レンダリング時にのみ処理を実行したいときは、第二引数の配列を空にして記述します。

App.js
import React, { useEffect } from 'react';

const App = () => {
  useEffect(() => {
    // 処理
  }, []);  // 第二引数の配列を空にする

  return (
    // JSX
  );
};

###任意の変数が変化したときのみ実行する
関数コンポーネント内で使用している変数に変化が生じたときに、useEffectに渡したコールバック関数を実行したいときには、第二引数の配列にその変数を指定します。
少し具体的な例として、ボタンを押すと数値が加算されるカウンターを作成してみます。

Counter.js
import React, { useState, useEffect } from 'react';

const Counter = () => {
  const [count, setCount] = useState(0);
  
  useEffect(() => {
    console.log('useEffect!!')
  }, [count]);  // 第二引数の配列に任意の変数を指定(ここではcountが変化した時のみ実行されるようにしている)

  return (
    <div>
      {count}
      <button onClick={() => setCount((prevCount) => prevCount + 1)}>
        ADD 1
      </button>
    </div>
  );
};

簡単な例ではありますが、このように記述することでcountが変化したときにのみuseEffectに渡しているコールバック関数が実行されます。

以上がuseEffectの基本的な使い方です。

#useEffectで非同期処理をする
useEffect内の() => {}には非同期関数または**promise**を返す関数を記述することができません。
ではどのようにuseEffectで非同期処理を行えばいいのでしょうか。
結論としては2通りの方法があります。

  • 方法1

 useEffectの外で別の関数を定義し、その関数をuseEffectで呼び出す

  • 方法2

 async, awaitを利用して特殊な記述をする

方法1については何となくイメージができると思いますので、ここでは方法2について詳しい記述方法を紹介します。

import React, { useEffect } from 'react';

const App = () => {

  useEffect(() => {
    (async () => {
      await // 処理
    })();
  }, [/* 任意の変数 */]);

  return (
    // JSX
  );
};

少し見慣れない書き方かもしれませんがこのように記述することで、useEffectで非同期処理を行うことができます。

誤って、

// BAD example!!
useEffect(async () => {
  await //  処理
}, [/* */])

としないように注意しましょう。

#まとめ
簡単ではありますが、useEffectについての説明は以上になります。
まとめると、

  • useEffect関数コンポーネントでライフサイクルメソッドを持たせるための機能
  • クラスコンポーネントで利用していたライフサイクルメソッドを一つの関数で表現できる
  • 記述の仕方で実行タイミングが変わる
  • 非同期処理させるためには注意が必要

といった感じです。

実際にはuseEffectの使い方としてはまだまだたくさんありますが、基本中の基本はこの記事にまとめてあることなのでしっかり抑えていただければと思います。
今後アプリケーションを作成する際に、適した使い方をしていきましょう。

また参考資料に記載しているリンク先ではさらに詳しい使い方や解説をしてくれていますので、是非みて見てください。

#参考資料

33
25
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
33
25

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?