基本:オブジェクトの分割代入
オブジェクトはキー名で指定して取り出す必要があります。順番は関係ありません。
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-form
の useForm
フックを使った例です。
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
になる(基本的にはエラーにはならない) - ネストされたオブジェクトの中身を取り出す場合、途中のオブジェクトが存在しないとエラーになる