2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

useEffectで非同期処理(async/ await)する際の注意点

Posted at

まず、useEffect の書き方。

// 第一引数に関数を渡す
useEffect(() => {
  // 実行させたい処理を記述する

  return () => { 
    // クリーンアップとして実行したい処理を記述する(省略可)
  }
  // 第二引数はuseEffectに渡したコールバック関数を実行したい場合に記述
  // 空配列だと初回のみ実行[]
},[])

非同期関数をuseEffect内で直接定義しない

useEffect内で非同期関数を直接定義することはできません。 useEffectのコールバック関数は同期的に実行されるため、非同期処理を行う場合は、useEffect内で非同期関数を呼び出す必要があります。

useEffect(() => {
  // 非同期関数を定義
  const fetchData = async () => {
    try {
      const response = await fetch('https://api.example.com/data');
      const data = await response.json();
      // データをセットする処理
      setData(data);
    } catch (error) {
      console.error('Error fetching data:', error);
    }
  };

  // 非同期関数を呼び出す
  fetchData();
}, []);

クリーンアップ処理を考慮する

非同期処理が完了する前にコンポーネントがアンマウント(DOMから削除)されると、状態更新時にエラーが発生することがあります。画面表示は無く、コンソールを見ると一度実行した処理が動き続けていてバグやメモリに多大な負荷がかかるなどです。

クリーンアップ関数は、useEffectの戻り値として関数を返します。

useEffect(() => {
  // 副作用の処理
  return () => {
    // クリーンアップ処理
  };
}, []);

また、クリーンアップ関数はコンポーネントがアンマウントされるか、依存配列の値が変わるたびに実行されます。これにより、古い副作用を解除し新しい副作用を適応することができるのです。

以下、クリーンアップ処理を考慮した例です。

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

const DataFetchingComponent = () => {
  const [data, setData] = useState(null); // データの状態を管理
  const [isMounted, setIsMounted] = useState(true); // マウント状態を追跡

  useEffect(() => {
    const fetchData = async () => {
      try {
        // APIリクエストを実行
        const response = await fetch('https://api.example.com/data');
        const result = await response.json();

        // コンポーネントがマウントされている場合のみ状態を更新
        if (isMounted) {
          setData(result);
        }
      } catch (error) {
        console.error('Error fetching data:', error);
      }
    };

    // 非同期関数の呼び出し
    fetchData();

    // クリーンアップ関数を返す
    return () => {
      // コンポーネントがアンマウントされたことを示すためのフラグを更新
      setIsMounted(false);
    };
  }, []); // 空の依存配列なのでコンポーネントのマウント時にのみ実行される(初回のみ実行される)

  // データがまだロードされていない場合のローディング表示
  if (!data) {
    return <div>Loading...</div>;
  }

  return (
    <div>
      <h1>Data</h1>
      <pre>{JSON.stringify(data, null, 2)}</pre>
    </div>
  );
};

export default DataFetchingComponent;

以上です。他にも useEffectの依存配列[] が注意点として挙げられますが、また躓いたら記事を書こうと思います。

2
0
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
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?