前回の記事では、コンポーネントの Props で子コンポーネントに値を渡す方法を解説しました。今回は、Props を「分割代入」を使って定義する方法を解説します。
C#や Java をメインに経験してきた私が、初めて分割代入による Props を見たときは戸惑いました。同じような経験をしている方に向けて、理解しやすい形でご説明します。
分割代入とは?Type Scriptで解説
まずは、Props を分割代入で書く前に、分割代入そのものを理解しておきましょう。
MDN Web Docs によると以下のように説明されています。
分割代入 (Destructuring assignment) 構文は、配列から値を取り出して、あるいはオブジェクトからプロパティを取り出して別個の変数に代入することを可能にする JavaScript の式です。
以下のサンプルコードで分割代入の動きと仕組みを確認しましょう。
// UserInfo型定義
type UserInfo = {
userName: string;
email: string;
password: string;
};
// UserInfo型のオブジェクトを生成する。
const user: UserInfo = {
userName: "taro",
email: "taro@sample.com",
password: "abcdef",
};
// 分割代入を使わない、一般的なオブジェクト内プロパティ参照方法。
console.log("user.userName", user.userName);
console.log("user.email", user.email);
console.log("user.password", user.password);
// コンソールログ出力結果:
// [LOG]: "user.userName", "taro"
// [LOG]: "user.email", "taro@sample.com"
// [LOG]: "user.password", "abcdef"
// 分割代入。UserInfoの各プロパティを独立したローカル変数に代入している。
const { userName, email, password } = user;
// 分割代入によってローカル変数に代入された値を参照。
console.log("userName", userName);
console.log("email", email);
console.log("password", password);
// コンソールログ出力結果:
// [LOG]: "userName", "taro"
// [LOG]: "email", "taro@sample.com"
// [LOG]: "password", "abcdef"
const { userName, email, password } = user;
というコードが分割代入です。左辺の変数名が右辺のオブジェクトのプロパティ名と一致している場合、そのプロパティの値が対応する変数に代入されます。この構文により、オブジェクトのプロパティの値を、直接ローカル変数に割り当てることができます。
- user オブジェクトから userName プロパティの値(”taro”)が新しい変数 userName に代入されます。
- 同様に、email プロパティの値(”taro@sample.com“)が変数 email に代入され、password プロパティの値(”abcdef”)が変数 password に代入されます。
さらに、別名(エイリアス)を使うことで、プロパティ名と異なる変数名を指定することも可能です。
const { userName: nameText, email: mail, password: pwd } = user;
console.log("nameText", nameText); // "taro"
console.log("mail", mail); // "taro@sample.com"
console.log("pwd", pwd); // "abcdef"
分割代入を使った Props の書き方
分割代入を使った Props の書き方には、主に 3 通りの方法があります。
以下のコンポーネントの Props を分割代入の形式で書くとどのような形になるか、見ていきましょう。
src/app/component/UserInputArea.tsx(分割代入を使わない Props の書き方):
export default function UserInputArea(props: {
userName: string;
email: string;
password: string;
}) {
return (
<>
<TextField
defaultValue={props.userName}
/>
</>
);
}
書き方 1:コンポーネント関数内で分割代入する
まずは、コンポーネント関数内で分割代入を行う書き方です
src/app/component/UserInputArea.tsx:
export default function UserInputArea(
props: {
userName: string,
email: string,
password: string
}) {
// Propsを分割代入する。
const { userName, email, password } = props;
return (
<>
{/* TextFieldの初期値をPropsの値にするため、defaultValue属性にPropsを指定する */}
<TextField
defaultValue={userName}
/>
</>
);
}
分割代入でローカル変数 userName に props.userName を代入したので、TextField の defaultValue 属性に指定する書き方が短くなっています。
- 従来:
defaultValue={props.userName}
- 分割代入:
defaultValue={userName}
書き方 2:引数で分割代入する
次に、引数の部分で直接分割代入を行う方法です。
src/app/component/UserInputArea.tsx:
// Propsの型定義
interface UserInputAreaProps {
userName: string;
email: string;
password: string;
};
export default function UserInputArea(
{
userName,
email,
password
}: UserInputAreaProps
) {
return (
<>
{/* props から値を取り出す手間を省き、直接プロパティ名を変数として利用できるようになります。 */}
<TextField
defaultValue={userName}
/>
</>
);
}
引数の部分で分割代入を行うことで、関数の中で明示的に分割代入を記述する手間を省けます。また、UserInputAreaProps 型を定義することで、Props の型を明確にすることができます。
書き方 3:引数で型定義と分割代入を同時に行う
最後に、型定義と分割代入を一緒に書く方法です。
export default function UserInputArea(
{
userName,
email,
password
}: {
userName: string;
email: string;
password: string;
}
) {
return (
<>
{/* props から値を取り出す手間を省き、直接プロパティ名を変数として利用できるようになります。 */}
<TextField
defaultValue={userName}
</>
);
}
こちらの方法では、Props の型定義を直接引数部分に記述します。型定義がシンプルな場合に適しています。
まとめ
分割代入を使った Props の書き方を解説しました。以下のポイントを押さえておきましょう。
- 分割代入とは:オブジェクトのプロパティを個別の変数に簡単に割り当てるための構文。
- Props に応用するメリット:
- コードが簡潔になる。
- 冗長な props. の記述を省ける。
- 型定義によって Props の構造が明確になる。
シチュエーションに応じて 3 つの方法を使い分けることで、より読みやすく保守しやすいコードを実現できます。