LoginSignup
2
2

More than 3 years have passed since last update.

[勉強用] React hooksで非同期処理を書く (ステップ5)

Last updated at Posted at 2019-07-01

はじめに

前ステップから続き、勉強用のuseFetchを書いていきます。今回のテーマはキャンセル処理です。

課題

URLを変更すると、クリーンアップ処理が走り、新しいデータ取得が走りますが、ブラウザが処理をしている前のデータ取得の処理を止めることができたわけではありません。例えば、長いデータを転送中だったり、サーバからの応答を待っていたり、サーバの名前解決をしていたりする場合は、データ取得の処理は継続しています。fetchはpromiseベースのAPIですが、AbortControllerを使うことで処理をキャンセル(abort)することができます。

ステップ5: キャンセル処理

const useFetch = url => {
  const [result, setResult] = useState({});
  useEffect(() => {
    let cleanedUp = false;
    const abortController = new AbortController();
    const fetchData = async () => {
      try {
        const response = await fetch(url, {
          signal: abortController.signal
        });
        if (!response.ok) throw new Error(`status: ${response.status}`);
        const data = await response.json();
        if (!cleanedUp) {
          setResult({ data });
        }
      } catch (error) {
        if (!cleanedUp) {
          setResult({ error });
        }
      }
    };
    setResult({ loading: true });
    fetchData();
    const cleanup = () => {
      cleanedUp = true;
      abortController.abort();
      setResult({});
    };
    return cleanup;
  }, [url]);
  return result;
};

念のため、cleanupでresultも初期化するようにしました。(一瞬以前のresultで描画されるを防ぐため)

動作確認

実際に動くコードはこちらです。codesandbox
キャンセルの動作はUIで直接は分かりませんので、Chrome DevToolsでNetworkタブを確認してください。

image.png

このように、ローディング中にURLを変更すると、canceledとなっていることを確認できると思います。

おわりに

本コードは勉強用ですので、そのままでは使わないでください。(ちゃんとした実装はこちら)
さらなる課題と解決は次のステップへ。

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