🐡

useEffectを用いて選択式プルダウンのチェーンを作る

2023/03/19に公開

useEffect を用いて選択式プルダウンのチェーンを作成する
完成系のイメージを下記します。

解説

ignore ってなんで設定されてる

Effect を使ってデータを取得してくる時に、Fetch を用いるのは一般的です。
引数に与えられた値によってデータを取得してくる場合、通信が複数回行われる可能性があります。
そんな時に、以下のような書き方で最新の Fetch 以外は無視するようにします。
下記のコードでは、複数回通信が行われると、DOM が unMount 時に ignore 変数が true に設定されます。
json が帰ってくる頃には、ignore は True になっているので、setTodos が実行されず、最新の通信のみ setTodos が実行されます。

useEffect(() => {
  let ignore = false;

  async function startFetching() {
    const json = await fetchTodos(userId);
    if (!ignore) {
      setTodos(json);
    }
  }

  startFetching();

  return () => {
    ignore = true;
  };
}, [userId]);

最初のレンダリング時に、planet のデータを取得する

useEffect の第二引数に空配列が渡されているので、レンダリング後初回しか呼び出されない。

useEffect(() => {
  let ignore = false;
  fetchData("/planets").then((result) => {
    if (!ignore) {
      console.log("Fetched a list of planets.");
      setPlanetList(result);
      setPlanetId(result[0].id); // Select the first planet
    }
  });
  return () => {
    ignore = true;
  };
}, []);

planet が変更したときに毎回通信を発生させてデータを取得したい

useEffect の第二引数に planetId が渡されることにより、planetId が変更した時に、下記 useEffect が実行される

useEffect(() => {
  if (planetId === "") {
    // Nothing is selected in the first box yet
    return;
  }

  let ignore = false;
  fetchData("/planets/" + planetId + "/places").then((result) => {
    if (!ignore) {
      console.log('Fetched a list of places on "' + planetId + '".');
      setPlaceList(result);
      setPlaceId(result[0].id); // Select the first place
    }
  });
  return () => {
    ignore = true;
  };
}, [planetId]);

最後に

意外と書けなかったので、メモメモ
間違っている箇所あれば、教えてください。

GitHubで編集を提案

Discussion