4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ネストされたオブジェクトの分割代入(react-hook-formでの利用例も紹介)

Posted at

基本:オブジェクトの分割代入

オブジェクトはキー名で指定して取り出す必要があります。順番は関係ありません。

const obj = { foo: 100, bar: 200 };
const { foo, bar } = obj;

console.log(foo); // 100
console.log(bar); // 200

存在しないキーを指定した場合も、値は undefined になります。

const { baz } = obj;
console.log(baz); // undefined

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

オブジェクトの中にオブジェクトがある場合、ネストして取り出すことができます。

const user = {
  name: "太郎",
  contact: {
    email: "taro@example.com",
    phone: "090-1234-5678"
  }
};

const {
  contact: { email, phone }
} = user;

console.log(email); // "taro@example.com"
console.log(phone); // "090-1234-5678"

このとき、contact という変数自体は定義されません。

console.log(contact); // ReferenceError: contact is not defined

エラーになるケース

ネストされたプロパティを取り出そうとした際、途中のオブジェクトが undefined の場合にはエラーになります。

const obj = {};
const { nested: { value } } = obj; // エラー

このような場合は、デフォルト値を指定して防ぐことができます。

const { nested: { value } = {} } = obj;

または、事前に空オブジェクトで安全に展開する方法もあります。

const { nested = {} } = obj;
const { value } = nested;

react-hook-formでの利用例

Reactでは、ライブラリの内部から提供されるオブジェクトを「分割代入」で効率よく扱うことがよくあります。

以下は、react-hook-formuseForm フックを使った例です。

import { useForm } from "react-hook-form";

export default function App() {
  const {
    register,
    handleSubmit,
    watch,
    formState: { errors },
  } = useForm();

  const onSubmit = (data) => console.log(data);

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input defaultValue="test" {...register("example")} />
      <input {...register("exampleRequired", { required: true })} />
      {errors.exampleRequired && <span>This field is required</span>}
      <input type="submit" />
    </form>
  );
}

この中の以下のコードに注目します。

const {
  formState: { errors },
} = useForm();

ここでは、useForm() が返すオブジェクトの中にある formState というプロパティから、さらに errors を取り出しています。

このことから、useForm() の戻り値はおおよそ以下のような構造になっていることが連想できますよね。

{
  register: ...,
  handleSubmit: ...,
  watch: ...,
  formState: {
    errors: { // ←注目、formStateプロパティのバリューさらにerrorsオブジェクトがあるはず
       ...,
      }
    },
    isDirty: true,
    isValid: false,
    // 他にもいろいろ
  },
  // 他にもいろいろ
}

このように、formState というオブジェクトの中にある errors を直接使いたい場合、ネストされた分割代入を使うことで次のように書けます。

const { formState: { errors } } = useForm();

こうしておくと、以降 errors.exampleRequired のように直接アクセスできるため、コードがすっきりします。

この構文は一見複雑に見えますが、前述のネストされたオブジェクトの分割代入とまったく同じ考え方です。

まとめ

  • オブジェクトはプロパティ名で対応付けられる
  • 存在しないキーを指定しても undefined になる(基本的にはエラーにはならない)
  • ネストされたオブジェクトの中身を取り出す場合、途中のオブジェクトが存在しないとエラーになる
4
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
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?