ReactのuseEffectフックについてわかりやすく解説

JavaScript
スポンサーリンク

ReactのuseEffectフックは、コンポーネントのライフサイクルにおける副作用(side-effects)を扱うためのものです。

この記事では、useEffectの基本的な使い方から応用例まで、具体的なコードを交えて解説します。

useEffectの具体例7選

まず、useEffectを利用した具体的なコードの例を示します。

1. コンポーネントがマウントされたときに一回だけ実行

import React, { useEffect } from 'react';

const App = () => {
  useEffect(() => {
    console.log("Component did mount.");
  }, []);

  return <div>Hello, World!</div>;
};

export default App;

解説: この例では、useEffectがコンポーネントがマウントされた直後に一回だけ実行されます。依存配列(第二引数)が空の配列([])であるためです。


2. 特定の状態が変わったときに実行

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

const App = () => {
  const [name, setName] = useState("John");

  useEffect(() => {
    console.log(`Name changed to ${name}.`);
  }, [name]);

  return (
    <div>
      <button onClick={() => setName("Jane")}>Change Name</button>
    </div>
  );
};

export default App;

解説: ここでは、nameという状態が変更されたときにuseEffect内の処理が実行されます。


3. 複数の状態に依存する場合

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

const App = () => {
  const [name, setName] = useState("John");
  const [age, setAge] = useState(30);

  useEffect(() => {
    console.log(`Name is ${name}, and age is ${age}.`);
  }, [name, age]);

  return (
    <div>
      <button onClick={() => setName("Jane")}>Change Name</button>
      <button onClick={() => setAge(35)}>Change Age</button>
    </div>
  );
};

export default App;

解説: nameまたはageが変更された場合にuseEffectが実行されます。依存配列に複数の状態を指定しています。


4. クリーンアップ(Cleanup)を行う場合

import React, { useEffect } from 'react';

const App = () => {
  useEffect(() => {
    const timer = setTimeout(() => {
      console.log("This will run after 1 second.");
    }, 1000);

    return () => {
      clearTimeout(timer);
      console.log("Cleanup.");
    };
  }, []);

  return <div>Hello, World!</div>;
};

export default App;

解説: useEffect内でタイマーを設定していますが、コンポーネントがアンマウントされる前にタイマーをクリアしています。これがクリーンアップ処理です。


5. 非同期処理を行う場合

import React, { useEffect } from 'react';

const App = () => {
  useEffect(() => {
    const fetchData = async () => {
      const res = await fetch("<https://api.example.com/items>");
      const data = await res.json();
      console.log(data);
    };

    fetchData();
  }, []);

  return <div>Hello, World!</div>;
};

export default App;

解説: useEffect内で非同期関数fetchDataを定義し、APIからデータを取得しています。


6. useEffectとlocalStorage

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

const App = () => {
  const [name, setName] = useState(localStorage.getItem("name") || "");

  useEffect(() => {
    localStorage.setItem("name", name);
  }, [name]);

  return (
    <div>
      <input
        type="text"
        value={name}
        onChange={(e) => setName(e.target.value)}
      />
    </div>
  );
};

export default App;

解説: name状態が変更されると、その新しい値がlocalStorageに保存されます。


7. useEffectとイベントリスナー

import React, { useEffect } from 'react';

const App = () => {
  useEffect(() => {
    const handleResize = () => {
      console.log(window.innerWidth);
    };

    window.addEventListener("resize", handleResize);

    return () => {
      window.removeEventListener("resize", handleResize);
    };
  }, []);

  return <div>Hello, World!</div>;
};

export default App;

解説: ウィンドウのサイズが変更されると、その新しい内部幅がコンソールに出力されます。コンポーネントがアンマウントされる際にイベントリスナーも削除されます。


これらの例と解説がuseEffectの理解に役立つことを願っています。何か他に質問があれば、どうぞお知らせください。

useEffectとは

useEffectはReactのフックの一つで、コンポーネントがマウントされた後、アンマウントされる前、または特定のプロップや状態が変更されたときに実行する処理を定義できます。

基本的な使い方

以下の例では、useEffectを使ってカウンターの値が変更されるたびにコンソールにその値を出力しています。

import { useEffect, useState } from "react";

const Counter = () => {
  const [count, setCount] = useState(0);

  useEffect(() => {
    console.log("Current Counter is ...", count);
  });

  return (
    <div>
      <button onClick={() => setCount(count + 1)}>Increment</button>
      <button onClick={() => setCount(count - 1)}>Decrement</button>
    </div>
  );
};

依存配列(Dependencies)

useEffectの第二引数には依存配列(deps)を指定できます。この配列に指定した変数が変更された場合のみ、useEffect内の処理が実行されます。

// countが変更された場合のみ実行される
useEffect(() => {
  console.log("Current Counter is ...", count);
}, [count]);

クリーンナップ関数

useEffect内で定義した処理が不要になった場合、クリーンナップ関数を使用してリソースを解放できます。

useEffect(() => {
  console.log("Subscribing...");
  // 何らかの購読処理

  return () => {
    console.log("Unsubscribing...");
    // 購読解除処理
  };
}, []);

非同期処理とuseEffect

useEffect内で非同期処理を行う場合は、async/awaitPromiseを使用できます。

async/awaitを使用した例

const fetchData = async () => {
  const res = await fetch("<https://api.example.com/data>");
  const data = await res.json();
  return data;
};

useEffect(() => {
  fetchData().then(data => {
    console.log(data);
  });
}, []);

まとめ

useEffectはReactの非常に強力なフックの一つです。コンポーネントのライフサイクルに応じて様々な処理を行うことができ、非同期処理とも簡単に組み合わせることができます。

この記事で紹介した基本的な使い方や応用例を参考に、useEffectを効果的に使用してください。