React PropType Array with Shape とは?
React PropType Array with Shape
特に、配列型のプロパティで、各要素が特定の形状(shape)を持つ必要がある場合、React.PropTypes.shape
を使うことで、より詳細な型チェックを行うことができます。
例
下記は、items
というプロパティが、name
とage
というプロパティを持つオブジェクトの配列であることを検証する例です。
import React from 'react';
import PropTypes from 'prop-types';
const MyComponent = ({ items }) => {
// ...
return (
<div>
{items.map((item) => (
<div key={item.name}>
<h1>{item.name}</h1>
<p>{item.age}</p>
</div>
))}
</div>
);
};
MyComponent.propTypes = {
items: PropTypes.arrayOf(
PropTypes.shape({
name: PropTypes.string.isRequired,
age: PropTypes.number.isRequired,
})
).isRequired,
};
export default MyComponent;
上記のコードでは、MyComponent
コンポーネントのitems
プロパティに対して、以下の検証が行われます。
items
は配列であること- 配列の各要素はオブジェクトであること
- オブジェクトには
name
とage
というプロパティが存在すること name
プロパティは文字列であること
詳細
React.PropTypes.shape
は、オブジェクトの形状を検証する際に非常に便利です。
以下の例では、address
プロパティが、street
とcity
というプロパティを持つオブジェクトであることを検証しています。
const MyComponent = ({ items }) => {
// ...
return (
<div>
{items.map((item) => (
<div key={item.name}>
<h1>{item.name}</h1>
<p>{item.address.street}</p>
<p>{item.address.city}</p>
</div>
))}
</div>
);
};
MyComponent.propTypes = {
items: PropTypes.arrayOf(
PropTypes.shape({
name: PropTypes.string.isRequired,
age: PropTypes.number.isRequired,
address: PropTypes.shape({
street: PropTypes.string.isRequired,
city: PropTypes.string.isRequired,
}),
})
).isRequired,
};
このように、React.PropTypes.shape
を使って、複雑な形状のオブジェクトも簡単に検証することができます。
React.PropTypes.oneOf
を使って、許可される値のリストを指定することができます。
React.PropTypes.shape
を使うことで、Reactコンポーネント間でデータを渡す際の型チェックをより詳細に行うことができます。
これは、コードの品質と信頼性を向上させるのに役立ちます。
import React from 'react';
import PropTypes from 'prop-types';
const MyComponent = ({ items }) => {
// ...
return (
<div>
{items.map((item) => (
<div key={item.name}>
<h1>{item.name}</h1>
<p>{item.age}</p>
</div>
))}
</div>
);
};
MyComponent.propTypes = {
items: PropTypes.arrayOf(
PropTypes.shape({
name: PropTypes.string.isRequired,
age: PropTypes.number.isRequired,
})
).isRequired,
};
export default MyComponent;
詳細
const MyComponent = ({ items }) => {
// ...
return (
<div>
{items.map((item) => (
<div key={item.name}>
<h1>{item.name}</h1>
<p>{item.address.street}</p>
<p>{item.address.city}</p>
</div>
))}
</div>
);
};
MyComponent.propTypes = {
items: PropTypes.arrayOf(
PropTypes.shape({
name: PropTypes.string.isRequired,
age: PropTypes.number.isRequired,
address: PropTypes.shape({
street: PropTypes.string.isRequired,
city: PropTypes.string.isRequired,
}),
})
).isRequired,
};
詳細は、React PropType API リファレンス: https://www.weblio.jp/content/%E5%89%8A%E9%99%A4。
React.PropTypes.shape の代替方法
- 冗長になりやすい
- 型定義ファイル (TypeScript など) を使用している場合は、重複が発生する
これらの欠点を克服するために、React.PropTypes.shape
の代わりに以下の方法を使用することができます。
TypeScript を使用している場合は、インターフェースを使用してオブジェクトの形状を定義することができます。
interface Item {
name: string;
age: number;
}
const MyComponent: React.FC<{ items: Item[] }> = ({ items }) => {
// ...
return (
<div>
{items.map((item) => (
<div key={item.name}>
<h1>{item.name}</h1>
<p>{item.age}</p>
</div>
))}
</div>
);
};
この方法を使用すると、React.PropTypes.shape
を使用する場合よりも簡潔で読みやすいコードになります。
zod ライブラリ
zod
は、オブジェクトのバリデーションを行うライブラリです。
import zod from 'zod';
const itemSchema = zod.object({
name: zod.string(),
age: zod.number(),
});
const MyComponent = ({ items }) => {
// ...
return (
<div>
{items.map((item) => {
itemSchema.parse(item); // バリデーション
// ...
return (
<div key={item.name}>
<h1>{item.name}</h1>
<p>{item.age}</p>
</div>
);
})}
</div>
);
};
この方法を使用すると、React.PropTypes.shape
よりも詳細なバリデーションを行うことができます。
自作のバリデーション関数
上記のいずれの方法も使用できない場合は、自作のバリデーション関数を作成することができます。
function validateItem(item) {
if (typeof item.name !== 'string') {
throw new Error('Invalid name');
}
if (typeof item.age !== 'number') {
throw new Error('Invalid age');
}
// ...
}
const MyComponent = ({ items }) => {
// ...
return (
<div>
{items.map((item) => {
validateItem(item); // バリデーション
// ...
return (
<div key={item.name}>
<h1>{item.name}</h1>
<p>{item.age}</p>
</div>
);
})}
</div>
);
};
この方法は、最も柔軟な方法ですが、コード量が増えてしまうという欠点があります。
これらの欠点を克服するために、上記の代替方法を使用することができます。
arrays reactjs react-proptypes