🤔

分割代入の使い方

2024/03/12に公開

はじめに

はじめまして。フロントエンドエンジニアを目指しているチョコ柿です。

最近TypeScriptとReactで個人開発をしているのですが、そこで使用しているReactQuery(今はTanstack Query)を調べてるときに、ふと目についた分割代入について書いていこうと思います。

結構いろんなところで出てきて、まだ見慣れない書き方をされる時もあるので、一旦まとめておこうという感じです。
何かご指摘等あれば、コメントで教えてくれると泣いて喜びます!ではでは。

分割代入とは

JavascriptやReactでよく出てくる構文で、以下のようなコードが基本文です。

const Obj = {
  name: "aaa",
  age: 20,
  state: "東京",
};

const { name, age, state } = Obj;
console.log(name); // aaaと出力される
console.log(age); // 20と出力される
console.log(state); // 東京と出力される

上記のようにオブジェクトのプロパティ名を{}で囲って代入することで、"name"などプロパティ名だけで出力できるようになります。
ちなみに、分割代入しなかった場合は以下のようになります。ちょっと記述がだるいですね。

const Obj = {
  name: "aaa",
  age: 20,
  state: "東京",
};

console.log(Obj.name); // aaaと出力される
console.log(Obj.age); // 20と出力される
console.log(Obj.state); // 東京と出力される

基本形を紹介したので、あとは私が「?」となった形の分割代入を紹介していこうと思います。

関数への分割代入

次は関数の戻り値に対する分割代入です。

function fn() {
  return {
    newName: "佐藤",
    newAge: 30,
  };
}

const { newName, newAge } = fn();
console.log(newName); //佐藤と出力される
console.log(newAge);// 30と出力される

Reactでよく見る形だと思います。
関数fnの中で処理しているプロパティ名を渡しています。
もちろんconst { newName, newAge } = fn();の部分で{name, age}とかで渡してしまうとundefinedになります。

ReactQueryでの分割代入

ReactQueryでよく使うAPIからデータを取得するときにも分割代入を使います。
先にコード例を記述します。

// API取得用のカスタムフック
const fetchInformations = async (): Promise<FetchData[]> => {
  const response = await fetch(
    "https://~~"
  );
  const data: FetchData[] = await response.json();
  return data;
};

export const useFetchData = () => {
  return useQuery({ queryKey: ["repoData"], queryFn: fetchInformations }); 
};
// コンポーネント
  const { data, isLoading, error } = useFetchData();

  if (isLoading) return <div>Loading...</div>;
  if (error) return <div>Failed to load...</div>;

今回この記事を書くきっかけになったコードは const { data, isLoading, error } = useFetchData();ここです。

API取得用のコードは公式Docに沿って記述していたのですが、isLoadingerrorなんてどこにも出てきません。しかし、実際に「Loading...」というreturnが成功していました。

どうやらReactQueryのuseQueryはデフォルトで以下のようなオブジェクトを返すようです。

{
  data: undefined, // APIからのレスポンスデータ
  error: null, // エラーオブジェクト
  isLoading: true, // ロード中かどうか
  isSuccess: false, // データの取得に成功したかどうか
  isError: false, // エラーが発生したかどうか
  // その他のプロパティ...
}

つまり、結局分割代入をしているだけだったということですねースッキリ。

初期値を指定した分割代入

次はプロパティに初期値を付与しているバージョンです。

  function fn() {
    return {
      newName: "佐藤",
      newAge: 30,
    };
  }

  const { newName = "", newAge } = fn();
  console.log(newName);
  console.log(newAge);

newNameというプロパティに初期値で空文字を設定しました。
これは、例えば戻り値でnewNameが返ってくるパターンと、返ってこないパターンが存在するときに使えたりします。

ネストされたオブジェクトの分割代入

次はネストされているオブジェクトを分割代入するときの書き方です。

export default function App() {
  const Obj = {
    name: "佐藤",
    address: {
      state: "東京都",
      city: "港区",
    },
  };

  const {
    name,
    address: { state, city },
  } = Obj;
  console.log(name); //佐藤が出力される
  console.log(state); //東京都が出力される
  console.log(city); // 港区が出力される

こんな感じです。
分割代入時にaddress: { state, city },と書くことで、使用するときにaddress.stateと書かなくて良くなります。

余談ですが、私は最初console.log(address)で出力してみようと思ったのですが、それだとどうなるでしょうか?
⇨undefinedとエラー吐かれちゃいます。
分割でstatecityを代入しているのでaddressは出力できないです。

仮にaddressをオブジェクトとして使いたい時は

const {
    name,
    address: { state, city },
    address
  } = Obj;

という形で加えると、オブジェクトとして使うことができるようになります。

終わりに

いかがでしたでしょうか?
あくまで一例ではありますが、詰まったところを紹介してみました。
皆さんの何かのお役に立てば幸いです!
X(twitter)もやっているので良ければフォローしてください!それでは!

Discussion