React Nativeの開発では、特定の機能を持った基底コンポーネントを作成し、それを再利用することがよくあります。ここでは、既存のベースコンポーネントに新たにPropsを追加する方法について説明します。
元となるコンポーネント
まず、出発点となるコンポーネントを見てみましょう。以下は一例となるCardコンポーネントです。
import React, { FC } from 'react';
import { View, ViewProps } from 'react-native';
type CardProps = ViewProps;
export const Card: FC<CardProps> = ({ children, ...rest }) => {
return (
<View {...rest}>
{children}
</View>
);
};
このCardコンポーネントは、子要素として任意のコンテンツを受け取ることができます。
このCardPropsの型は、ViewPropsとして定義されています。ViewPropsはReact Nativeが提供する型で、Viewコンポーネントが受け取ることができる全てのプロップスの型定義を含んでいます。これにより、このCardコンポーネントもViewと同じプロップを受け取ることができます。
新しいPropsの追加
次に、このCardコンポーネントに、新たなプロップとしてonCloseを追加しましょう。これは、ユーザーが閉じるアクションを行ったときにトリガーされるイベントハンドラを想定します。
新たなプロップを追加するには、まず、新たなプロップの型を定義します。ここでは、onClose関数の型は() => voidとします。
そして、この新たなプロップをCardPropsに追加します。
interface CardProps extends ViewProps {
onClose: () => void;
}
コンポーネントへの適用
最後に、新たに追加したonCloseプロップをCardコンポーネントに適用します。
import React, { FC } from 'react';
import { View, ViewProps, TouchableOpacity } from 'react-native';
import { CloseIcon } from '../icons/CloseIcon';
interface CardProps extends ViewProps {
onClose: () => void;
}
export const Card: FC<CardProps> = ({ onClose, children, ...rest }) => {
return (
<View {...rest}>
<TouchableOpacity onPress={onClose}>
<CloseIcon />
</TouchableOpacity>
{children}
</View>
);
};
新たなonCloseプロップはCardPropsインターフェースに追加され、Cardコンポーネントの引数にも追加されました。これにより、親コンポーネントからこの関数がプロップとして渡されるようになり、ユーザーがCloseIconをタップしたときにこれがトリガーされるようになります。
ここで注目したいのは、...restという記述です。これはJavaScriptの「残余パラメータ(rest parameter)」と呼ばれる構文で、いくつかのアイテムを一つの配列にまとめることができます。この場合、Cardコンポーネントが受け取る全てのプロップをrestオブジェクトにまとめ、それをViewコンポーネントに渡しています。つまり、Cardコンポーネントが受け取る全てのプロップ(onCloseとchildrenを除く)は、そのままViewコンポーネントに渡されます。
まとめ
React Nativeで汎用的なコンポーネントを作成し、それを再利用する際には、新たなプロップを追加してコンポーネントをカスタマイズすることがよくあります。この記事ではその方法を具体的に説明しました。また、React NativeのViewPropsとJavaScriptの「残余パラメータ」についても解説しました。これらを理解し活用することで、コンポーネントの再利用性と可読性が向上します。